Map
map 函数在python3里面不再像以前一样,返回的是结果集,现在它返回的是一个map object
Map对象也相当于一个生成器表达式,同样拥有next()方法
>>> map((lambda x:x),(1,2,3))
<map object at 0xb714b7ac>
>>> F=map((lambda x:x),(1,2,3)) #所以说map对象也是一个可迭代对象,每次只求一个值
>>> next(F)
1
可以通过list函数或列表解析来实现对map对象进行循环调用
>>> list(map(abs,(-1,2,-4)))
[1, 2, 4]
>>> [i for i in map(abs,(-1,2,-4))]
[1, 2, 4]
Map对象每一次next()方法返回的都是经过expr处理过后的表达式的值,如F=map(iter,((1,2,3),(5,4),(6,7))) 它每次得到的就是元组迭代对象
Range
Range 函数返回一些列连续增加的整数,可用作for中的索引,指定重复的次数
>>> list(range(5, -5, -2)) #第一个为“下限”,第三个为步值
[5, 3, 1, -1, -3]
>>> for i in range(3): #等价与C++中 for (i=0,i<3,i++)
... print(i, 'Python')
其实我以前一直有个疑问就是:比如形式for i in range(6),它是先求出(0,1,2,3,4,5)这个结果集,然后变成形式for i in (0,1,2,3,4,5)把后面当成一个元组进行处理,还是你每执行一次循环,range对象求一个值赋给你呢?
我当时之所以这么认为,因为感觉for i in file,你看人家file就是一个整体数据块在那放着,而range(6)是不是也得先转换为一个数据块呢?其实完全有点进入误区了。你只需把他们两个都当成对象就行了,对于对象file,每一次循环它都是把next(temp)赋值给i;然后我range(6)也就类似呗,每一次也都将next(temp)赋值给i就行了。只是它俩的表现形式是对于file,它是取得了一行数据,而range(6)我们是得到了一个数,看着可能有点疑问,我本身是一个range(6)对象,怎么最后会出来一个数字呢?可以想象的是range对象中的next方法肯定是return一个迭加数值,或者说是yield出来一个值。。
编译结束后,是否是一个数据块等待着你来进行处理,关键是看它的next方法,到底是返回一个generator object,还是一个列表解析;最直接的方式就是把给嵌套函数赋予相应的值,查看它的结果
>>> a=range(6)
>>> a
range(0, 6) #从结果可以看出它是每一次循环才求出一个值付给i
>>> next(a)
TypeError: range object is not an iterator
>>> temp=iter(a)
>>> next(temp)
0
>>> next(temp)
1
>>> temp2=iter(a)
>>> next(temp2)
0
list
list 对对象进行iter调用,然后for循环加入到一个元组中。
>>> list('me')
['m', 'e']
>>> list((1,2,3))
[1, 2, 3]
>>> list(((1,2,3),(4,5,6)))
[(1, 2, 3), (4, 5, 6)]
>>> list(2,3,3)
TypeError: list() takes at most 1 argument (3 given)
>>> list((1,2,3),(4,5))
TypeError: list() takes at most 1 argument (2 given)
list 可以对一个迭代对象,循环处理,并返回每次循环结果组成的元组,相当于进行列表解析
>>> M=map(pow,(1,2,3),(4,5,6)) #我们前面已经说了,现在的map函数是返回一个map object 不再是结果集
>>> M
<map object at 0xb714aa8c>
>>> list(M)
[1, 32, 729]
>>> [i for i in map(pow,(1,2,3),(4,5,6))] #列表解析形式
[1, 32, 729]
并行遍历zip
函数返回并行元素的元组的列表,
zip不仅仅是用于列表,同样可以用于string,Zip会以最短序列长度为准来截断所得到的元组
>>> L1 = [1,2,3,4]
>>> L2 = [5,6,7,8]
>>> zip(L1,L2)
[(1, 5), (2, 6), (3, 7), (4, 8)]
>>> for (x,y) in zip(L1,L2)
根据下面的输出结果,我们可以知道如果zip在被嵌入调用的时候,它是随着循环一次求出一个值,然后付给i
>>> Z=zip((1,2,3),(3,4))
>>> Z
<zip object at 0xb714aa6c>
>>> next(Z)
(1, 3)
>>> next(Z)
(2, 4)
>>> list(zip((1,2,3),(3,4))) #list等价与列表解析,对它进行for循环输出显示
[(1, 3), (2, 4)]
>>> list(zip((1,2)))
[(1,), (2,)]
Dict构造字典
平时让你写字典的话,很简单,直接大括号里面键值对就行。但是如果就给你两个列表呢?可以zip和内置函数dict
>>> keys = ['spam', 'egg', 'toast']
>>> vals = [1,3,5]
>>> D3 = dict(zip(keys,vals))
>>> D3
{'toast': 5, 'egg': 3, 'spam': 1}
enumerate 产生偏移和元素
>>> s = 'spam'
>>> e = enumerate(s)
>>> e
<enumerate object at 0xb72938c4>
>>> next(e) #第一次next读的是第一个元素
(0, 's')
>>> for (offset,item) in enumerate(s):
... print (item, 'appear at offset', offset) #因为它每次返回一个元组包含两项,一项位移,一项元素值
...
('s', 'appear at offset', 0)
('p', 'appear at offset', 1)
('a', 'appear at offset', 2)
('m', 'appear at offset', 3)
下面是一个易错点
>>> L=[1,2,3,4,5] #我们想使列表中每个元素都加1,方式一会失败。
>>> for x in L:
... x +=1
...
>>> L
[1, 2, 3, 4, 5]
>>> for i in range(len(L)): #千万别用形式in L,因为你想当于对L遍历,这个并不会造成死循环,但却会有出界问题。
... L[i] +=1
...
>>> L
[2, 3, 4, 5, 6]
Iter
是产生一个对象的迭代器,也就是说它里面可以储存访问所指对象的状态信息。例如对对象next()到那个位置了。
>>> F=map(iter,((1,2,3),(5,4),(6,7)))
>>> F
<map object at 0xb710550c>
>>> for i in F:
... print(i)
... print(next(i))
...
<tuple_iterator object at 0xb710574c> #每次next都会指向下一层,就现在而言是元组的开头
1
<tuple_iterator object at 0xb710576c>
5
<tuple_iterator object at 0xb710574c>
6