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