例子
#for x in [1,2,3]: #列表 # print(x) #for x in (1,2,3): #元组 # print(x)
文件本身也是个可迭代的对象:
创建一个new file:data.txt在里面写入
优品课堂
学编程 好心情
www.codeclassroom.com
www.youpinketang.com
www.uke.cc
再在main.py里写入
f = open('data.txt',encoding='utf8') for line in f: #for line在刚才的f里 print(line, end=' ') #遍历出来结果的行,结尾用空格结束
1、迭代协议:_next_()
_next_()不是暴露出来给客户调用,可以获取下一个元素,就是一行一行读 next:所占内存空间不变的情况,如果想获得数据,移到下一项,移动指针用的
pyhon console里写入
f = open('data.txt',encoding='utf8')
f.__next__()
'优品课堂\n'
典型支持迭代协议对象
>>> f = open('data.txt',encoding='utf8') >>> next(f) '优品课堂\n' >>> next(f) '学编程 好心情\n' >>> next(f) 'www.codeclassroom.com\n'
>>>f = open ('data.txt',encoding='utf8') >>> for x in f.readlines(): #返回一个列表,把所有行找到放到list里,不写ReadLines好,数据大不支持还是用for...open更好不占太多内存 ... print(x) ... 优品课堂 学编程 好心情 www.codeclassroom.com www.youpinketang.com www.uke.cc
调用全局函数直接写next
列表:可迭代的对象
>>> urls = ['youpinketang.com','uke.cc','codeclassroom.com'] >>> for url in urls: ... print(url) ... youpinketang.com uke.cc codeclassroom.com
2、迭代工具for...推导...map...
(1)迭代对象
(2)可迭代对象
f = open('data.txt',encoding='utf8') f.__next__() '优品课堂\n' for i in [1,2,3]: print(i) 1 2 3 f = open('data.txt',encoding='utf8') for line in f: print(line) 优品课堂 学编程 好心情 www.codeclassroom.com www.youpinketang.com www.uke.cc
结果一样差别在于f本身具备next方法,但是列表没有
iter(f) is f#iter全局函数包起来f判断一下f是不是应用了迭代器功能,返回true证明使用next方法 True
>>> f = open('data.txt',encoding='utf8') >>> iter(f) is f #iter全局函数包起来f判断一下f是不是应用了迭代器功能,返回true证明使用next方法 True True >>> f.__next__() '优品课堂\n' >>> next(f)#把f传进去本质同上 '学编程 好心情\n'
列表:不具有上面的功能,套一个进去就可以用了
>>> iter(urls) is urls #判断列表是否本身有迭代器,发现不是 False >>> i = iter(urls)#所以没有next,用for实现,或迭代器等于urls把刚才的传进去 >>> i.__next__() 'youpinketang.com'
>>> next(i)
'uke.cc'
手动迭代,返回一个列表中所有元素,要平方值
法1使用for 次啰嗦
>>> l = [1,2,3] >>> res = [] #做个空列表 >>> for x in l: ... res.append(x**2) #装列表的最加x平方项 ... >>> res [1, 4, 9]
法2手动实现不用for 最啰嗦
>>> i = iter(l) #iter全局的方法把列表加进去 >>> while True: ... try: ... ... x = res.append(next(i) ** 2) # i里取个值放入res里,追加 ... ... except StopIteration: # 捕获异常跳出循环 ... ... break >>> res [1, 4, 9, 1, 4, 9]
法3实际开发,手推导 推荐使用
result = [x**2 for x in l] result [1, 4, 9]
字典表
用for找元素
>>> emp = {'name':'Tom','age':20,'job':'dev','salary':8000.00} >>> for k,v in emp.items(): ... ... print(k,v) ... name Tom age 20 job dev salary 8000.0 >>> emp.items()#看items类型,发现不是列表虽然很像 dict_items([('name', 'Tom'), ('age', 20), ('job', 'dev'), ('salary', 8000.0)]) >>> for k in emp: ... ... print(k) ... name age job salary >>> emp.keys()#看所有键 dict_keys(['name', 'age', 'job', 'salary']) >>> emp.values()#也不是列表 dict_values(['Tom', 20, 'dev', 8000.0])
不用for找挨个元素
>>> keys = emp.keys()#先声明一个keys,看类型 >>> keys dict_keys(['name', 'age', 'job', 'salary']) >>> iter(keys) is keys#看是keys本身吗false不包含next方法 False >>> i = iter(keys) >>> i.__next__() 'name' >>> i.__next__() 'age' >>> i.__next__() 'job' >>> i.__next__() 'salary'
可迭代都可放入推导表达式内,推导的基础:前半截是返回的结果,中间是过滤的过程,后面if是过滤的条件:res4 = [url for url in urls if url.endswith('.com')]#过滤,地址包含.com
>>> l = [1,2,3,4,5] >>> res1 = [x for x in l]#在l遍历,每个元素放稳定变量x,取x本身放入x,[]表示返回列表 >>> type(res1) <class 'list'> >>> res1 [1, 2, 3, 4, 5] >>> res2 = [x+10 for x in l] #列表找单个数把数字每个加10 >>> res2 [11, 12, 13, 14, 15] >>> urls = ['youpinketang.com','uke.cc','codeclassroom.com'] >>> res3 = [url.upper() for url in urls]#变大写 >>> res3 ['YOUPINKETANG.COM', 'UKE.CC', 'CODECLASSROOM.COM'] >>> res4 = [url for url in urls if url.endswith('.com')]#过滤,地址包含.com >>> res4 ['youpinketang.com', 'codeclassroom.com']
法2 繁琐
>>> res5 = [] >>> for x in urls: ... ... if x.endswith('.com'): ... ... res5.append(x) ... >>> res5 ['youpinketang.com', 'codeclassroom.com']
3、内置可迭代对象 range()生成序列,它不是列表虽然和列表很像
>>> range(50) range(0, 50) >>> r = range(1,20)#1-20序列 >>> type(r) <class 'range'> >>> for x in range(1,11): ... print(x) ... 1 2 3 4 5 6 7 8 9 10 >>> result = [x**2 for x in range(1,6)]#1-5平方值算出 >>> result [1, 4, 9, 16, 25]
可迭代对象 :1自己实现next方法 2 没有
range用法:
测试
>>> r = range(1,6) >>> iter(r) is r #r生成的迭代器是它本身吗 False
不允许
>>> r = range(1,6) >>> iter(r) is r False >>> i = iter(r) #r自动生成next方法 >>> i.__next__() 1 >>> next(i)#也可用全局的方法 2
zip用法:将连个集合合成一个,本质也是可迭代对象
>>> result = zip(['x','y','z'],[1,2,3]) #xyz调用123 >>> result>>> for x in result:#遍历 ... ... print(x) #结果变成元组 ... ('x', 1) ('y', 2) ('z', 3)
map用法:main.py 把一个数字乘以2
def double_number(x): return x * 2 l = [1,2,3,4,5] result = list(map(double_number,l) ) #把l列表的每一个元素都应用函数double nmber,map是挨个传播 print(result)
函数:
1目的:最大化代码重用dry不用重复自己
最小化代码冗余
过程分解
2定义:def函数名(参数1,...):函数体
如计算两数相乘
def multiply(x, y): return x * y
3调用:函数名(实际参数)
def multiply(x, y): return x * y print(multiply(3.14,5))
试试字符串能否相乘,发现可以:字符串的特性
print(multiply('优品课堂',5))
模拟看书过程:封装执行语句形成命令
def read_book():#重复利用()表面执行操作 print('拿到一本书')#逻辑 print('看书') print('收起') read_book()#调用函数
#接收参数传递信息 def learning(): print('报名') print('学习') print('退出') learning()
细化信息:通过参数形式列举
#接收参数传递信息 def learning(name, course, start, end):#需要给相应的参数,形式参数 print('{}报名课程:《{}》'.format(name,course))#格式化字符串 print('从第{}节学习到第{}节.format(start, end)') print('{}学习结束.format(name)') learning('Tom','Python入门',1,3)#实际应用,实际参数
可以从外面向里面传递信息,也可以从里面向外面传递信息
#learning('Tom','Python入门',1,3)#实际应用 def add_number(x,y): #计算两个数据和,add添加数字 result = x + y #先声明一个result return result #返回一个值给调用者 #print(add_number(5,3)) a = 10 result = a + add_number(5,3) print(result)
假定两个序列找重复序列
def intersect(seq1, seq2): #两个序列以为是列表 res = []#放入空列表 for x in seq1: #找第一个序列元素放x里,声明参数是在本地定义一个变量 if x in seq2: #如果第二个也有也放进去 res.append(x) #放入空列表里 return res s1 = 'uke.cc' s2 = 'youpinketang.com' l = intersect(s1, s2)#放入一个新结果 print(l)#打印看有哪些
换
s1 = 'abcdefg'
实际开发方便用推导
4变量作用域
(1)Global全局:global
(2)local本地
x = 55 def func():#定义函数,函数里定义的作用的范围是它里面的属于本地的(local) x = 99 #赋值99 print(x) print('全局x:',x) print('函数内x:')#函数内x为多少 func()# func是执行逻辑
全局55 内99
如果想用全局的加个global
x = 55 def func():#定义函数 global x x = 99 #x为外部的 print(x) print('全局x:',x) print('函数内x:')#函数内x为多少 func()# func是执行逻辑 print('全局x:',x)
第一次:函数没执行是55,第二次x是外部的了,把x给改了打印的是99,第三次x已经改变所以为99
(3)built-in:作用最范围广
(4)enclousure封装 :nonlocal
函数套函数:逻辑是先定义再调用
def func():#定义函数 x = 100#第二次打印的是外侧x,外层x称之为封装 def nested():#嵌套 x = 99 print(x) nested()#调用,第一次执行的是它 print(x) func()#func执行,自带print
答案:99 100
有时候也想用外侧的,可写声明nonlocal 非本地的
def func():#定义函数 x = 100#第二次打印的是外侧x,外层x称之为封装 def nested():#嵌套 nonlocal x #非本地的 x = 99 print(x) nested()#调用,第一次执行的是它 print(x) func()#func执行,自带print
答案:99 99
5参数
改变数字
def change_numer(x):#默认情况下参数定义没有写类型 x += 10 x = 5 #传x为5整型不可改变 print('x={}'.format(x))#第一次打印x change_numer(x) #执行改变操作 print('x={}'.format(x))#第二次再打x
答案:5 5
改变列表
def change_list(l): l[0] = 99#传递过来的列表第一个元素标记为99 l = ['uke.cc','codeclassroom.com','youpinketang.com'] print('原始列表:',l) change_list(l) print('操作后列表:',l)
答案:
原始列表: ['uke.cc', 'codeclassroom.com', 'youpinketang.com']
操作后列表: [99, 'codeclassroom.com', 'youpinketang.com']
改变字符串
def change_str(s): s = 'uke.cc' url = 'youpinketang.com' print(url) change_str(url) print(url)
答案:
youpinketang.com
youpinketang.com
规律:参数 传递 不可变类型,传递副本给函数,函数内操作不影响原始值(int,float,str,tuple)
可变类型,传递地址引用,函数内操作可能会影响原始值(列表,字典表)
不变类型直接操作值,而列表只是个引用,改变了会影响它的值。