1.16 过滤序列元素
1.使用列表推导式
>>> mylist = [1, 4, -5, 10, -7, 2, 3, -1]
>>> [n for n in mylist if n > 0]
[1, 4, 10, 2, 3]
缺点:当结果集很大的时候,会占用大量内存。也可以使用生成器表达式来迭代产生过滤的元素
>>> pos = (n for n in mylist if n > 0)
>>> pos
at 0x1006a0eb0>
>>> for x in pos:
... print(x)
...
1
4
10
2
3
>>>
过滤规则复杂的情况下,可以使用内建的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)
# Outputs ['1', '2', '-3', '4', '5']
此外还介绍了itertools.compress()
原理:先创建一个 Boolean 序列,指示哪些元素符合条件。 然后 compress() 函数根据这个序列去选择输出对应位置为 True 的元素
filler()和itertools.compress()返回的都是迭代器对象,如果需要列表的话,需要使用list()转换
1.17 从字典中提取子集
1.字典推导式
prices = {
'ACME': 45.23,
'AAPL': 612.78,
'IBM': 205.55,
'HPQ': 37.20,
'FB': 10.75
}
# Make a dictionary of all prices over 200
p1 = {key: value for key, value in prices.items() if value > 200}
# Make a dictionary of tech stocks
tech_names = {'AAPL', 'IBM', 'HPQ', 'MSFT'}
p2 = {key: value for key, value in prices.items() if key in tech_names}
1.18 映射名称到序列元素
主要是通过collections.namedtuple()来命名元组
>>> from collections import namedtuple
>>> Subscriber = namedtuple('Subscriber', ['addr', 'joined'])
>>> sub = Subscriber('jonesy@example.com', '2012-10-19')
>>> sub
Subscriber(addr='jonesy@example.com', joined='2012-10-19')
>>> sub.addr
'jonesy@example.com'
>>> sub.joined
'2012-10-19'
>>>
使用_repalce()改变属性的值
命名元组也可以使用字典来实现。因为字典存储需要更多的内存空间。 如果你需要构建一个非常大的包含字典的数据结构,那么使用命名元组会更加高效。
1.19 转换并同时计算数据
1.生成器表达式
nums = [1, 2, 3, 4, 5]
s = sum(x * x for x in nums)
1.20 合并多个字典或映射
使用 collections 模块中的 ChainMap 类
a = {'x': 1, 'z': 3 }
b = {'y': 2, 'z': 4 }
from collections import ChainMap
c = ChainMap(a,b)
print(c['x']) # Outputs 1 (from a)
print(c['y']) # Outputs 2 (from b)
print(c['z']) # Outputs 3 (from a)
一个 ChainMap 接受多个字典并将它们在逻辑上变为一个字典。 然后,这些字典并不是真的合并在一起了, ChainMap 类只是在内部创建了一个容纳这些字典的列表 并重新定义了一些常见的字典操作来遍历这个列表
作为 ChainMap 的替代,你可能会考虑使用 update() 方法将两个字典合并,但是它需要你创建一个完全不同的字典对象(或者是破坏现有字典结构)。 同时,如果原字典做了更新,这种改变不会反应到新的合并字典中去。
ChainMap 使用原来的字典,它自己不创建新的字典。所以它并不会产生上面所说的结果
>>> a = {'x': 1, 'z': 3 }
>>> b = {'y': 2, 'z': 4 }
>>> merged = ChainMap(a, b)
>>> merged['x']
1
>>> a['x'] = 42
>>> merged['x'] # Notice change to merged dicts
42
>>>
至此,python-cookbook的第一章节 数据结构与算法就结束了,总体发现,该书更多侧重介绍python中的函数来实现一些算法。对与其算法的原理并没有侧重介绍。因此更适合老手,对新手来讲,掌握算法的原理还是比较重要的。