16过滤序列元素python
itertools.compress()app
最简单的方式是用list表达式过滤 >>> 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 <generator object <genexpr> at 0x7efdb34b6d20> >>> for i in pos: ... print i ... 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 ... >>> filter(is_int,values) ['1', '2', '-3', '4', '5'] 另外一个比较实用的过滤器是itertools.compress(),须要一个迭代元素和一个对应的boolean序列做为输入 >>> from itertools import compress >>> counts = [ 0, 3, 10, 4, 1, 7, 6, 1] >>> more5 = [n > 5 for n in counts] >>> more5 [False, False, True, False, False, True, True, False] >>> compress(counts,more5) <itertools.compress object at 0x7efdb347c190> compress返回的是一个迭代序列,须要用list()进行类型转换 >>> list(compress(counts,more5)) [10, 7, 6]
17生成dict的子序列spa
prices = { 'ACME': 45.23, 'AAPL': 612.78, 'IBM': 205.55, 'HPQ': 37.20, 'FB': 10.75 }>>> p1 = { key:value for key, value in prices.items() if value > 200 } >>> p1 {'AAPL': 612.78, 'IBM': 205.55}
18将name映射到序列元素
collections.namedtuple()是一个工厂方法,返回一个标准的tuple类型的子集,你须要提供类型名称和应该有的域.prototype
>>> from collections import namedtuple >>> Subscriber = namedtuple('Subscriberxx', ['addr', 'joined']) 程序中,'Subscriberxx'是类型名称, ['addr', 'joined']是域 >>> sub = Subscriber('jonesy@example.com', '2012-10-19') >>> sub Subscriberxx(addr='jonesy@example.com', joined='2012-10-19') namedtuple()虽然像一个类实例,实际上确实和tuple交互支持经常使用的tuple操做,如索引和解包 >>> len(sub) 2 >>> addr, joined = sub >>> addr 'jonesy@example.com' >>> joined '2012-10-19'
namedtuple()的一个重要用处是取代dict,dict须要更多的存储空间,当须要建包含大量dict的数据时用namedtuple()更高效,但有一点须要注意,namedtuple()是不可变的,(tuple是不可变的) .code
若是须要改变,则使用_replace(),这会产生一个新的 >>> Stock = namedtuple('Stock', ['name', 'shares', 'price']) >>> s = Stock('ACME', 100, 123.45) >>> s.share=75 Traceback (most recent call last): File "<stdin>", line 1, in <module> AttributeError: 'Stock' object has no attribute 'share' >>> s=s._replace(shares=75) >>> s Stock(name='ACME', shares=75, price=123.45) 咱们能够利用_replace()建立一个包含默认值的原型 >>> Stock = namedtuple('Stock', ['name', 'shares', 'price', 'date', 'time']) >>> stock_prototype = Stock('', 0, 0.0, None, None) >>> def dict_to_stock(s): ... return stock_prototype._replace(**s) ... >>> a = {'name': 'ACME', 'shares': 100, 'price': 123.45} >>> dict_to_stock(a) Stock(name='ACME', shares=100, price=123.45, date=None, time=None) >>> b = {'name': 'ACME', 'shares': 100, 'price': 123.45, 'date': '12/17/2012'} >>> dict_to_stock(b) Stock(name='ACME', shares=100, price=123.45, date='12/17/2012', time=None) >>>
19同时转换和归并数据
orm
>>> nums = [1, 2, 3, 4, 5] >>> s = sum((x * x for x in nums)) # 显示的传递一个生成器表达式对象 >>> s = sum(x * x for x in nums)# 更加优雅的实现方式,省略了括号 >>> s 55 使用生成器是更优雅和高效的方式,应为省去了建立一个临时的tuple或list的损耗
20将多个映射合并为一个
collections.ChainMap(仅python3适用)对象
>>> from collections import ChainMap >>> a = {'x': 1, 'z': 3 } >>> b = {'y': 2, 'z': 4 } >>> c = ChainMap(a,b) >>> c ChainMap({'x': 1, 'z': 3}, {'z': 4, 'y': 2}) >>> c['x'] 1 >>> c['y'] 2 >>> c['z'] 3 ChainMap只是把多个映射逻辑上组合在一块儿,若是有多个相同的key,则取第一个 >>> len(c) 3 >>> list(c.keys()) ['x', 'z', 'y'] >>> list(c.values()) [1, 3, 2] 对ChainMap的操做只会对第一个映射产生影响 >>> c['z']=10 >>> c['w']=3 >>> del c['x'] >>> c ChainMap({'w': 3, 'z': 10}, {'z': 4, 'y': 2}) >>> a {'w': 3, 'z': 10} >>> del c['y'] --------------------------------------------------------------------------- KeyError Traceback (most recent call last) <ipython-input-5-df3e26fa6544> in <module>() ----> 1 del c['y'] /usr/lib/python3.4/collections/__init__.py in __delitem__(self, key) 866 del self.maps[0][key] 867 except KeyError: --> 868 raise KeyError('Key not found in the first mapping: {!r}'.format(key)) 869 870 def popitem(self): KeyError: "Key not found in the first mapping: 'y'" --------------------------------------------------------------------------- ChainMap还能够用new_child(),parents添加和删除映射 >>> values=ChainMap() >>> values['x']=1 >>> values=values.new_child() >>> values['x']=2 >>> values=values.new_child() >>> values['x']=3 >>> values ChainMap({'x': 3}, {'x': 2}, {'x': 1}) >>> values['x'] 3 >>> values=values.parents >>> values ChainMap({'x': 2}, {'x': 1}) >>> values['x'] 2 有一种取代ChainMap的方式是用update() >>> a = {'x': 1, 'z': 3 } >>> b = {'y': 2, 'z': 4 } >>>b.update(a) >>> b {'x': 1, 'z': 3, 'y': 2} >>> a {'x': 1, 'z': 3} >>> a['x']=13 >>> a {'x': 13, 'z': 3} >>> b {'x': 1, 'z': 3, 'y': 2} ****************** 这两种方式有一个重要的区别,update原dict的改变不会影响到合并后的dict,但ChainMap会 ****************** >>> a = {'x': 1, 'z': 3 } >>> b = {'y': 2, 'z': 4 } >>> merged = ChainMap(a, b) >>> merged['x'] 1 >>> a['x']=32 >>> merged['x'] 32