第五天:迭代、函数定义与参数

一、迭代

1、迭代协议

  • next()
  • 可迭代对象内部实现了f.__next__()方法
f = open('course.txt',encoding = 'utf8')
f.__next__() #两个下划线
f.__next__() 
next(f)
'优品\n'
'Hello world!\n'
'www.codeclassroom.com'
  • next()方法与__next__都是每次只打印一行
f = open('course.txt', encoding = 'utf8')
next(f)
next(f)
next(f)
next(f)
'优品\n'
'Hello world!\n'
'www.codeclassroom.com'
StopIteration:  #报错

2、迭代工具 for...推导...map...

迭代器对象==>已经实现

iter()用于生成迭代器

iter(f) is f
f.__next__()
True
StopIteration:  #报错

列表List并没有内置

urls = ['youpinhung.com','ashduah.com','aisuoiwq.com']
iter(urls) is urls
False

但是我们可以使用iter()函数来转换:

i = iter(urls)
i.__next__()
'youpinhung.com'
i = iter(l)
while True:
    try:
        x = res.append(next(i)**2)
    except StopIteration:
        break
res
[1, 4, 9, 1, 4, 9]

可迭代对象

  • iter()-->__iter()__用于生成迭代器
emp = {'name':'Tom', "age":20,'job':'dev', 'salary':4000.0}
keys = emp.keys()
iter(keys) is keys
False #字典中的键也不是可迭代对象
i = iter(keys)
i.__next__()
next(i)
'name'
'age'
res5 = []
for x in urls:
    if x.endswith('.com'):
        res5.append(x)
res5
['youpinhung.com', 'ashduah.com', 'aisuoiwq.com']

内置可迭代对象

  • range()
r = range(1,20)
type(r)
result = [x**2 for x in range(1,6)]
result
range
[1, 4, 9, 16, 25]
  • map()
r = range(1, 6)
iter(r) is r
False
i = iter(r)
i.__next__()
next(i)
1
2
  • zip()
result = zip(['x', 'y', 'z'], [1,2,3])
for x in result:
    print(x)
('x', 1)
('y', 2)
('z', 3)
result.__next__()
StopIteration: 
def double_number(x):
    return x * 2
l = [1,2,3,4,5]
result = list(map(double_number,l)) #map函数
print(result)
[2, 4, 6, 8, 10]

二、函数

1、why

  • 最大化代码重用
  • 最小化代码冗余
  • 过程分解

    2、定义

  • def 函数名(参数1,...):函数体
def learning(name, course, start, end):
    print('{}报名课程:《{}》'.format(name, course))
    print('从第{}节学习到第{}节'.format(start, end))
    print('{}学习结束'.format(name))
learning('Tom', 'Python入门', 1,3)
Tom报名课程:《Python入门》
从第1节学习到第3节
Tom学习结束

3、调用

  • 函数名(实际参数)
def intersect(seq1, seq2): #寻找字符串共同点
    res = []
    for x in seq1:
        if x in seq2:
            res.append(x)
            
    return res

s1 = 'uke.cc'
s2 = 'youpinketang.com'
l = intersect(s1, s2)
print(l)
['u', 'k', 'e', '.', 'c', 'c']

4、变量作用域

  • Built-in
    正常示例
x = 55 
def func():
    x = 99
    print(x)
print('全局x:',x)
print('函数内x:')
func()
全局x: 55
函数内x:
99
  • Global---global
x = 55 
def func():
    global x #在这里,表示的是,如果运行这个函数,那么x的值55就要变成全局变量99
    x = 99
    print(x)
print('全局x:',x)
print('函数内x:')
func()
print('全局x:', x)
全局x: 55
函数内x:
99
全局x: 99
  • Enclousure---nonlocal
def func():
    x = 100
    def nested():
        x = 99
        print(x)
    nested()
    print(x)
func() 
99
100
def func():
    x = 100
    def nested():
        nonlocal x
        x = 99
        print(x) #这里打印出来的x是99
    nested()
    print(x)
func() #运行完函数就改变x的值为99,故打印出99
99
99

nonlocal与global主要区别有以下两点:
1、 两者的功能不同。
global关键字修饰变量后标识该变量是全局变量,对该变量进行修改就是修改全局变量,而nonlocal关键字修饰变量后标识该变量是上一级函数中的局部变量,如果上一级函数中不存在该局部变量,nonlocal位置会发生错误(最上层的函数使用nonlocal修饰变量必定会报错)。
2、 两者使用的范围不同。
global关键字可以用在任何地方,包括最上层函数中和嵌套函数中,即使之前未定义该变量,global修饰后也可以直接使用,而nonlocal关键字只能用于嵌套函数中,并且外层函数中定义了相应的局部变量,否则会发生错误。

def func():
    x = 100
    def nested():
        global x
        x = 99
        print(x) #这里打印出来的x是99
    nested()
    print(x)
func() #运行完函数就改变x的值为99,故打印出99
99
100
  • Local

    5、参数

  • 传递
    • 不可变类型,传递副本给函数,函数内操作不影响原始值
    def change_number(x):
      x += 10
      return x
    x = 5
    print('x = {}'.format(x))
    change_number(x)
    print('x = {}'.format(x))
    x = 5
    x = 5
    def change_number(x):
      x += 10
      return x
    x = 5
    print('x = {}'.format(x))
    x = change_number(x) #上下两个打印的第二个x的值不同的原因,在于有没有把x指向新的对象
    print('x = {}'.format(x))
    x = 5
    x = 15
    • 可变类型,传递地址引用,函数内操作可能会影响原始值
    def change_list(l):
      l[0] = 99
    l = ['udk.cc', 'cdofiweod.com', 'dshudh.com']
    print('原始列表:',l)
    change_list(l)   #这里的列表被改变了
    print('操作后列表:', l)
    原始列表: ['udk.cc', 'cdofiweod.com', 'dshudh.com']
    操作后列表: [99, 'cdofiweod.com', 'dshudh.com']

    解决不可变类型方法:

    def change_list(l):
      l[0] = 99
    l = ['udk.cc', 'cdofiweod.com', 'dshudh.com']
    print('原始列表:',l)
    change_list(l.copy())   #这里的列表不被改变
    print('操作后列表:', l)
    原始列表: ['udk.cc', 'cdofiweod.com', 'dshudh.com']
    操作后列表: ['udk.cc', 'cdofiweod.com', 'dshudh.com']

猜你喜欢

转载自www.cnblogs.com/linyk/p/11449191.html