码迷,mamicode.com
首页 > 其他好文 > 详细

5 迭代与推导

时间:2018-02-03 20:01:11      阅读:107      评论:0      收藏:0      [点我收藏+]

标签:item   决定   文件   lambda   情况下   tuple   project   test   pyc   

1 迭代

 1 #迭代器对象、可迭代对象之前提到过好多次了,其实我自己也不太明白具体的含义
 2 #今天就来研究研究
 3 #先来看看几种常见的用for循环遍历对象的场景吧
 4 for x in [1,2,3]:
 5     pass
 6 
 7 for y in (1,2,3):
 8     pass
 9 
10 d = {a:1,b:2}
11 for item in d.items():
12     pass
13 
14 #f = open(‘data.txt‘,‘r‘,encoding=‘UTF-8‘)
15 #for i in f:
16 #    pass
17 
18 #为什么这几种数据类型都可以被for循环遍历呢?
19 #因为它们都是可迭代对象,实现了迭代协议
20 #可迭代对象支持__next__()函数,能够获取到可迭代对象的下一个元素。
21 #此外还有一个全局函数next()有可以遍历可迭代对象。
22 #print(next(f))
23 
24 #由于文件对象f是可迭代对象,所有可以用for循环进行遍历
25 #for x in f.readlines():
26 #    pass
27 #f.readlines()就是将文件内容的每一行作为一个元素全部放在一个list中,如果文件太大
28 #list也会很大,就基表消耗内存了
29 #由此也可以引出可迭代对象的优势,不必把list所有元素都加载到内存中,从中
30 #取一个元素处理一个元素,如此占用的资源小,故在实际开发中,遇到要处理的数据量
31 #特别大的情况,使用可迭代对象比较好。
32 
33 l = [1,2,3,4,5]
34 #print(l.__next__())
35 
36 #报错啦:
37 #Traceback (most recent call last):
38 #  File "C:/Users/dddd/PycharmProjects/untitled5/test.py", line 34, in <module>
39 #    print(l.__next__())
40 #AttributeError: ‘list‘ object has no attribute ‘__next__‘
41 
42 #可见,列表并没有实现可迭代协议,之所以能用for遍历,是因为:for语句帮它多做了一步操作
43 #就是用iter()函数将其转化为迭代器对象。
44 #所以列表可以称之为可迭代对象。
45 
46 #可迭代对象的本质是实现了__next__()函数,有如下两种情况
47 #一:迭代器对象(自己已经实现了__next__())
48 #二:可迭代对象(借助for等迭代工具用iter()将其转化为迭代器对象,就能遍历了,如list就是这样)
49 
50 #实际开发中,发现一个对象可以用for进行遍历,如何确认它是迭代器对象还是可迭代对象
51 #如果一个对象自己可以调用__next__(),就是迭代器对象;
52 #如果一个对象自己不可以调用__next__(),但可用for等迭代工具遍历的就是可迭代对象。
53 
54 #还有一个方法区分而知,就是用iter()来判断
55 print(iter(l) is l)
56 #如果返回True,说明l自己已经实现了__next__()函数,因为iter()函数的作用就是帮助对象实现__next__()函数,所以这种是迭代器对象
57 #如果返回False,说明l自己没有实现__next__()函数,若可用for遍历,就是可迭代对象。
58 
59 #可迭代对象可以用iter()函数转化为迭代器对象
60 a = [www.baidu.com,www.alibaba.com,www.tensen.com]
61 a1 = iter(a)  #将a转化为迭代器对象a1
62 print(iter(a1) is a1)   #返回结果为:True,说明a1是迭代器对象
63 
64 #除了借助iter()帮助实现__next__(),还可以手动实现
65 s = www.baidu.com
66 print(iter(s) is s)   #False,说明字符串不是迭代器对象
67 
68 s1 = s[:]
69 s2 = iter(s1)
70 print(s2.__next__())   #w
71 
72 #到这可能会问了,我为什么要费劲巴拉转换呢,直接用for来遍历不就好了吗?
73 #上边也提到了,将可迭代对象转化为迭代器对象,可以在数据量比较大的情况下节省内存开支
74 #这一点在实际开发中比较重要,毕竟计算机的内存是有限的。
75 
76 l = [1,2,3,4,5,6,7]
77 res = []
78 for x in l:
79     res.append(x**2)
80 
81 #如果l很大,这个资源消耗就很大了。
82 
83 #所以下边尝试手工把l这个可迭代对象转化为迭代器对象
84 ll = iter(l)
85 res1 = []
86 while True:
87     try:
88         x = next(ll)  #这样就做到处理哪个元素就把哪个元素加载到内存中
89         res1.append(x**2)
90     except StopIteration:
91         break
92 
93 print(res1)  #[1, 4, 9, 16, 25, 36, 49]
94 
95 
96 #据说啊,列表之所以没有自动实现__next__(),是因为雷彪中还可以存放其他的数据结构,比如再嵌套一个列表、元组、字典、函数名等。

可迭代对象实现了可迭代协议
可迭代对象包括list、tuple、file、generator等
迭代工具:上下文、for、map、comprehension、推导,应用在可迭代对象上,将可迭代对象作为参数传递给iter()
返回迭代器对象,然后迭代工具调用next()处理可迭代对象。

 

2 推导

 1 #说起效率,最高的还是推导,因为在解释器中是使用c语言实现的
 2 l = [1,2,3,4,5]
 3 res1 = [x**2 for x in l]
 4 print(res1)   #[1, 4, 9, 16, 25, 36, 49]
 5 
 6 #in l 表示要遍历的范围
 7 #for 后的 x 用于存放每次循环获得的临时变量
 8 #x**2 这部分表示获取的元素如何处理
 9 #推导返回的数据类型由外侧的括号类型决定,如[]表示返回列表,()表示返回元组。
10 
11 #新需求,给l中的每个元素都加10
12 res2 = [(x + 10) for x in l]
13 print(res2)  #[11, 12, 13, 14, 15]
14 
15 url = [www.xxx.com,www.yyy.cn]
16 #只取url列表中以‘.com‘结尾的元素
17 res3 = [x for x in url if x.endswith(.com)]
18 print(res3)  #[‘www.xxx.com‘]
19 
20 #还记得range类型吗,是可迭代对象,可以手动转化为迭代器对象
21 r = range(0,5)
22 i = iter(r)
23 print(i)              #<range_iterator object at 0x0000000000E8AF30>
24 print(i.__next__())   #0
25 print(next(i))        #1
26 
27 #还记得上节课学习的函数工具吗?
28 #列表推导与map()
29 score = [66,77,47,38,88,99]
30 #需求:给每门成绩加2分
31 #实现方法一:推导
32 scores = [ (x + 2) for x in score]
33 
34 #实现方法二:用map()
35 m = map(lambda x:x+2,score)
36 scoress = list(m)
37 
38 #列表推导与filter()
39 #需求:筛选出及格的成绩
40 #实现方法一:推导
41 score1 = [x for x in score if x >= 60 ]
42 
43 #实现方法二:filter()
44 def fun(x):
45     if x >= 60:
46         return True
47 
48 f = filter(fun,score)
49 score2 = list(f)

 

5 迭代与推导

标签:item   决定   文件   lambda   情况下   tuple   project   test   pyc   

原文地址:https://www.cnblogs.com/avention/p/8407476.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!