Python高级特性之:List Comprehensions、Generator、Dictionary and set comprehensions
2014-05-22 19:45
766 查看
我们在需要循环处理数据的时候,往往都会用range(n)这个方法生成list但是如果需要生成奇数list或者其他list怎么办呢?这就是我今天要讲的List Comprehensions。
需要注意的是: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.
】
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 = [expr for iter_var in iterable if cond_expr]:加了判断条件if cond_expr,也就是满足了判断条件才按expr运算iter_var。
注:还有很多其他用法,有需求,就有使用的空间,简单写两个。
官方demo:https://wiki.python.org/moin/Generators 建议迭代的时候能用generator就用!
为什么我推荐生成器呢。因为list大的时候很占内存,会受到内存限制;如果我们需要用的元素少,岂不是浪费得很?
generator的机制为:一边循环,一边计算!
有些是不能用List
Comprehensions写出来的,例如斐波那契数列用,怎么办呢? 百度百科:斐波拉契数列 维基百科:菲波拉契数列
斐波那契数列,又称黄金分割数列,指的是这样一个数列:0、1、1、2、3、5、8、13、21、……在数学上,斐波纳契数列以如下被以递归的方法定义:F0=0,F1=1,Fn=F(n-1)+F(n-2)(n>=2,n∈N*)。
这个就需要用函数了!但是普通函数不能生成generator,需要用到yield关键字。
首先不得不说下generator值的取法:用for循环;用next()方法。
原因是:它并不把所有的值放在内存中,它是实时地生成数据,所以只可以取值一次!
其他的迭代器方法,如下图:
Help on generator object:
<genexpr> = class generator(object)
| Methods defined here:
| close(...)
| close() -> raise GeneratorExit inside generator.
| # 抛出generator内部的GeneratorExit异常,达到停止generator的目的
| x.next() -> the next value, or raise StopIteration
| # 取下一个值,所有都取过则抛出异常StopIteration
| send(...)
| send(arg) -> send 'arg' into generator,
| return next yielded value or raise StopIteration.
| # 传递参数进入generator,返回下一个yielded的值直到抛出StopIteration异常。
| throw(...)
| throw(typ[,val[,tb]]) -> raise exception in generator,
| return next yielded value or raise StopIteration.
| # 未知用法,暂未涉及
| ----------------------------------------------------------------------
下面用斐波那契数列学习generator:
b中的b的值,下次调用时候,又从yield处开始执行,并且执行到下一个yield处暂停,并抛出当前yield
b中的b的值。(本例子中有个while循环!)下面是程序运行过程:
【更新于:2014.07.08另外一种实现方法
】
新特性:2.7.X版本及3.2以上版本。本节内容2014.09.25更新。
set和dict表达式
本文由@The_Third_Wave原创。不定期更新,有错误请指正。
Sina微博关注:@The_Third_Wave
如果这篇博文对您有帮助,为了好的网络环境,不建议转载,建议收藏!如果您一定要转载,请带上后缀和本文地址。
一、List Comprehensions(列表解析/列表生成器)
方法一:循环l.append()
>>> 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用法
【2014.06.01补充:生成奇偶数其实可以用range,但是本文讲的是list comprehensions。>>> range(0, 10,2) [0, 2, 4, 6, 8]
】
方法三:使用List Comprehensions
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 <generator object <genexpr> 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] >>>下面会讲生成器。
注:还有很多其他用法,有需求,就有使用的空间,简单写两个。
1、多层循环
>>> 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]
2、用等连接字典的键值:key=value
>>> d = {1: 'A', 2: 'B', 3: 'C' } >>> [str(k) + '=' + v for k, v in d.iteritems()] ['1=A', '2=B', '3=C'] >>>
二、Generator(生成器)
官方demo:https://wiki.python.org/moin/Generators 建议迭代的时候能用generator就用!为什么我推荐生成器呢。因为list大的时候很占内存,会受到内存限制;如果我们需要用的元素少,岂不是浪费得很?
generator的机制为:一边循环,一边计算!
generator的创建方法:
1、把List Comprehensions中的[]换为(),上面有例子,不在贴出代码。
有些是不能用ListComprehensions写出来的,例如斐波那契数列用,怎么办呢? 百度百科:斐波拉契数列 维基百科:菲波拉契数列
斐波那契数列,又称黄金分割数列,指的是这样一个数列:0、1、1、2、3、5、8、13、21、……在数学上,斐波纳契数列以如下被以递归的方法定义:F0=0,F1=1,Fn=F(n-1)+F(n-2)(n>=2,n∈N*)。
这个就需要用函数了!但是普通函数不能生成generator,需要用到yield关键字。
2、yield关键字
首先不得不说下generator值的取法:用for循环;用next()方法。>>> L = (i for i in range(10) if i % 2 != 1) >>> L <generator object <genexpr> 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 "<pyshell#6>", line 1, in <module> L.next() StopIteration >>> for i in L: print i >>>我们发现了什么?L的值被取过一遍后再也取不出来了!next()会报错,for 循环取不出来任何值。
原因是:它并不把所有的值放在内存中,它是实时地生成数据,所以只可以取值一次!
其他的迭代器方法,如下图:
Help on generator object:
<genexpr> = class generator(object)
| Methods defined here:
| close(...)
| close() -> raise GeneratorExit inside generator.
| # 抛出generator内部的GeneratorExit异常,达到停止generator的目的
>>> L = (i for i in range(10) if i % 2 != 1) >>> L.next() 0 >>> L.close() >>> L.next() Traceback (most recent call last): File "<pyshell#18>", line 1, in <module> L.next() StopIteration >>>| next(...)
| x.next() -> the next value, or raise StopIteration
| # 取下一个值,所有都取过则抛出异常StopIteration
| send(...)
| send(arg) -> send 'arg' into generator,
| return next yielded value or raise StopIteration.
| # 传递参数进入generator,返回下一个yielded的值直到抛出StopIteration异常。
| throw(...)
| throw(typ[,val[,tb]]) -> raise exception in generator,
| return next yielded value or raise StopIteration.
| # 未知用法,暂未涉及
| ----------------------------------------------------------------------
下面用斐波那契数列学习generator:
>>> 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) <generator object fbnq at 0x02A1C760> >>> 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 "<pyshell#70>", line 1, in <module> 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] >>>
】
三、Dictionary and set comprehensions
新特性: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
如果这篇博文对您有帮助,为了好的网络环境,不建议转载,建议收藏!如果您一定要转载,请带上后缀和本文地址。
相关文章推荐
- Python高级特性之:List Comprehensions、Generator、Dictionary and set comprehensions
- Python高级特性之Generator
- 转载:Python高级特性 生成器(generator)
- python 高级特性:Generator(生成器)
- python高级特性之生成器(generator)
- python高级特性-生成器(generator)
- python高级特性(生成器generator )
- Python高级特性
- 从0开始学quantum之1:Python高级特性--装饰器
- Python高级特性(1):Iterators、Generators和itertools
- Python_高级特性
- Python高级特性(2):Closures、Decorators和functools
- set up Android development environment and python
- python学习笔记16:tuple, set, dictionary
- Python的高级特性之切片、迭代、列表生成式、生成器
- Python高级特性(2):Closures、Decorators和functools(转)
- python : list tuple set dictionary [转]
- Django中的Python高级特性
- Python的高级特性