|
楼主 |
发表于 2015-6-13 22:23:56
|
显示全部楼层
[python cookbook]
问题:你有一个数据序列,想利用一些规则从中提取出需要的值或者是缩短序列
解决:使用列表推导生成器表达式
先看看列表推导:
- >>> mylist = [1, 4, -5, 10, -7, 2, 3, -1]
- >>> [n for n in mylist if n > 0]
- [1, 4, 10, 2, 3]
- >>> [n for n in mylist if n < 0]
- [-5, -7, -1]
复制代码 PS:相信稍微学习了一些python的鱼油对于列表推导都不陌生,这是很有python特色的一个工具,但是有一个问题,当列表很大时,我们使用列表推导会占用大量的内存,这个时候如果能有生成式就好,生成式每次用到下一个对象时即时计算而不提前计算好放在内存中,看下面的例子- >>> pos = (n for n in mylist if n > 0)
- >>> pos
- <generator object <genexpr> at 0x1006a0eb0>
复制代码 PS:可以看到这里的pos是一个生成式,原来直接把方括号变成圆括号就可以得到生成式,这也是我看这节所学到的
另外,当遇到更复杂的情况时,你需要使用filter函数
- values = ['1', '2', '-3', '-', '4', 'N/A', '5']
- def is_int(val):
- try:
- x = int(val)
- return True
- except ValueError:
- return False
- ivals = list(filter(is_int, values))
- print(ivals)
复制代码 输出是这样的- >>>
- ['1', '2', '-3', '4', '5']
复制代码 另外 一个需要注意的是itertools模块中的compress函数(PS:吐槽一下,itertools里面的东西还真是好用啊),它以一个 iterable 对象和一个相对应的Boolean选择器序列作为输入参数。 然后输出 iterable 对象中对应选择器为True的元素。 当你需要用另外一个相关联的序列来过滤某个序列的时候,这个函数是非常有用的。比如下面的例子中想将那些对应count值大于5的地址全部输出- addresses = [
- '5412 N CLARK',
- '5148 N CLARK',
- '5800 E 58TH',
- '2122 N CLARK'
- '5645 N RAVENSWOOD',
- '1060 W ADDISON',
- '4801 N BROADWAY',
- '1039 W GRANVILLE',
- ]
- counts = [ 0, 3, 10, 4, 1, 7, 6, 1]
复制代码 我们这样做- >>> from itertools import compress
- >>> more5 = [n > 5 for n in counts]
- >>> more5
- [False, False, True, False, False, True, True, False]
- >>> list(compress(addresses, more5))
- ['5800 E 58TH', '4801 N BROADWAY', '1039 W GRANVILLE']
- >>>
复制代码 其实用filter函数重新定义一个函数也可以做到,不过这样做似乎更直观一些(PS:compress是压缩的意思,函数名起的真好啊)最后,列表推导还有这样的用法
- >>> clip_neg = [n if n > 0 else 0 for n in mylist]
- >>> clip_neg
- [1, 4, 0, 10, 0, 2, 3, 0]
- >>> clip_pos = [n if n < 0 else 0 for n in mylist]
- >>> clip_pos
- [0, 0, -5, 0, -7, 0, 0, -1]
- >>>
复制代码 这其实是列表推导 和条件赋值组合使用的结果,条件赋值比如:- >>> a = 10
- >>> b = 1 if a < 5 else 2
- >>> print(b)
- 2
- >>> a = 3
- >>> c = 1 if a < 5 else 2
- >>> c
- 1
复制代码 上面的例子根据a的大小是否小于5来决定b和c的赋值~~
|
|