一、迭代
1、迭代协议
- next()
- 可迭代对象内部实现了f.next()方法
f = open('course.txt',encoding = 'utf8')
f.__next__() #两个下划线
f.__next__()
next(f)
'优品
'
'Hello world!
'
'www.codeclassroom.com'
- next()方法与__next__都是每次只打印一行
f = open('course.txt', encoding = 'utf8')
next(f)
next(f)
next(f)
next(f)
'优品
'
'Hello world!
'
'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()
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']