我们在需要循环处理数据的时候,往往都会用range(n)这个方法生成list但是如果需要生成奇数list或者其他list怎么办呢?这就是我今天要讲的List Comprehensions。
>>> L = []
>>> for i in range(10):
if i % 2 == 1:
L.append(i)
>>> L
[1, 3, 5, 7, 9]
需要注意的是:xrange()消耗的内存小,只做迭代处理的话,推荐一律用xrange()。
help()原文:Like range(), but instead of returning a list, returns an object that generates the numbers in the range on demand. For looping, this is slightly faster than range() and more memory efficient.
>>> range(0, 10,2)
[0, 2, 4, 6, 8]
List Comprehensions语法:[expr for iter_var in iterable] 或 [expr for iter_var in iterable if cond_expr]
L = [expr for iter_var in iterable]:for iter_var in iterable的作用是依次取 iterable赋值给iter_var,而expr for iter_var in iterable的作用就是依次取值给iter_var,expr做运算后,继续循环,expr运算得到的值赋给变量L
>>> L = [i % 2 == 1 for i in range(10)]
>>> L
[False, True, False, True, False, True, False, True, False, True]
>>> L = [i + 1 for i in range(5)]
>>> L
[1, 2, 3, 4, 5]
>>>
请注意上面两个表达式的不同结果。
L = [expr for iter_var in iterable if cond_expr]:加了判断条件if cond_expr,也就是满足了判断条件才按expr运算iter_var。
>>> L = (i for i in range(10) if i % 2 ==1)
>>> L
at 0x02950F80>
>>> for i in L:
print i
1
3
5
7
9
需要注意的是:第二种方法返回的不是一个list是一个generator(生成器)对象!为什么呢,我们用的是()而不是[],
是不是有人写错了?
>>> L = [i for i in range(10) if i % 2 ==1]
>>> L
[1, 3, 5, 7, 9]
>>>
下面会讲生成器。
注:还有很多其他用法,有需求,就有使用的空间,简单写两个。
>>> L = [a * b for a in range(1, 10) for b in range(1, 10)]
>>> L
[1, 2, 3, 4, 5, 6, 7, 8, 9, 2, 4, 6, 8, 10, 12, 14, 16, 18, 3, 6, 9, 12, 15, 18, 21, 24, 27, 4, 8, 12, 16, 20, 24, 28, 32, 36, 5, 10, 15, 20, 25, 30, 35, 40, 45, 6, 12, 18, 24, 30, 36, 42, 48, 54, 7, 14, 21, 28, 35, 42, 49, 56, 63, 8, 16, 24, 32, 40, 48, 56, 64, 72, 9, 18, 27, 36, 45, 54, 63, 72, 81]
>>> d = {1: 'A', 2: 'B', 3: 'C' }
>>> [str(k) + '=' + v for k, v in d.iteritems()]
['1=A', '2=B', '3=C']
>>>
>>> L = (i for i in range(10) if i % 2 != 1)
>>> L
at 0x029518A0>
>>> for i in L:
print i
0
2
4
6
8
>>> for i in L:
print i
>>>
有没有疑问呢?再看next()方法是什么样的。
>>> L = (i for i in range(10) if i % 2 != 1)
>>> L.next()
0
>>> L.next()
2
>>> L.next()
4
>>> L.next()
6
>>> L.next()
8
>>> L.next()
Traceback (most recent call last):
File "", line 1, in
L.next()
StopIteration
>>> for i in L:
print i
>>>
我们发现了什么?
L的值被取过一遍后再也取不出来了!next()会报错,for 循环取不出来任何值。
>>> L = (i for i in range(10) if i % 2 != 1)
>>> L.next()
0
>>> L.close()
>>> L.next()
Traceback (most recent call last):
File "", line 1, in
L.next()
StopIteration
>>>
| next(...)
>>> def fbnq(max):
# 生成max个元素的斐波那契数列
L = []
a, b, n = 0, 1, 0
while n < max:
L.append(b)
a, b = b , a + b
n += 1
return L
>>> fbnq(10)
[1, 1, 2, 3, 5, 8, 13, 21, 34, 55]
>>>
我们能构建1个list的斐波那契数列,那么generator的怎么构建呢?很简单!
>>> def fbnq(max):
# 生成max个元素的斐波那契数列
a, b, n = 0, 1, 0
while n < max:
yield b
a, b = b , a + b
n += 1
>>> fbnq(8)
>>> G.next()
1
>>> G.next()
1
>>> G.next()
2
>>> for i in G:
print i
3
5
8
13
21
>>>
为什么会这样呢?由于有关键字yield,我们构建的第二个函数就不是普通的函数了,而是一个generator。
工作原理是:程序执行时,遇到yield就会停下来,并返回当前yield b中的b的值,下次调用时候,又从yield处开始执行,并且执行到下一个yield处暂停,并抛出
当前yield b中的b的值。(本例子中有个while循环!)下面是程序运行过程:
>>> def fbnq(max):
# 生成max个元素的斐波那契数列
a, b, n = 0, 1, 0
while n < max:
print "A"
yield b
a, b = b , a + b
n += 1
print "B"
>>> G = fbnq(5)
>>> G.next()
A
1
>>> G.next()
B
A
1
>>> G.next()
B
A
2
>>> G.next()
B
A
3
>>> G.next()
B
A
5
>>> G.next()
B
Traceback (most recent call last):
File "", line 1, in
G.next()
StopIteration
>>>
【更新于:2014.07.08另外一种实现方法
>>> def fbnq():
a, b = 0, 1
while True:
yield a
a, b = b , a + b
>>> from itertools import islice
>>> list(islice(fbnq(), 10))
[0, 1, 1, 2, 3, 5, 8, 13, 21, 34]
>>>
】
新特性:2.7.X版本及3.2以上版本。本节内容2014.09.25更新。
set和dict表达式
a = {x: x*x for x in range(6)}
a
Out[9]: {0: 0, 1: 1, 2: 4, 3: 9, 4: 16, 5: 25}
type(a)
Out[10]: dict
b = {('a'*x) for x in range(6)}
b
Out[12]: {'', 'a', 'aa', 'aaa', 'aaaa', 'aaaaa'}
type(b)
Out[13]: set
本文由@The_Third_Wave原创。不定期更新,有错误请指正。
Sina微博关注:@The_Third_Wave
如果这篇博文对您有帮助,为了好的网络环境,不建议转载,建议收藏!如果您一定要转载,请带上后缀和本文地址。