1. 迭代對象解壓賦值
解壓賦值操作可以應(yīng)用到任何迭代對象上丛肢,如:列表
、元組
剿干、字符串
蜂怎、文件對象
、迭代器
置尔、生成器
杠步。
唯一的要求:
- 變量的數(shù)量必須跟序列元素的數(shù)量是一樣的。
>>> p=(1,2,3,4)
>>> a,b,c,d=p
>>> a
1
>>> b
2
>>> c
3
>>> d
4
>>> datas=['apple', 'cherry', 1, (1,2,3,4)]
>>> a,b,c,d=datas
>>> a
'apple'
>>> b
'cherry'
>>> c
1
>>> d
(1, 2, 3, 4)
>>> s='faris'
>>> a,b,c,d,e=s
>>> a
'f'
>>> b
'a'
>>> c
'r'
>>> d
'i'
>>> e
's'
2. 擴(kuò)展迭代對象解壓賦值
如果遇到不確定個(gè)數(shù)或任意個(gè)數(shù)元素的可迭代對象時(shí)榜轿,則需要使用星號表達(dá)式可以用來解決這個(gè)問題幽歼。
假設(shè)你現(xiàn)在有一些用戶的記錄列表,每條記錄包含一個(gè)名字谬盐、郵件甸私,接著就是不確定數(shù)量的電話號碼。
>>> record = ('Dave', 'dave@example.com', '773-555-1212', '847-555-1212')
>>> name, email, *phone_numbers = record
>>> name
'Dave'
>>> email
'dave@example.com'
>>> phone_numbers
['773-555-1212', '847-555-1212']
>>>
如果你想解壓一些元素后丟棄它們设褐,你不能簡單就使用 * 颠蕴, 但是你可以使用一個(gè)普通的廢棄名稱,比如 _ 或者 ign (ignore)助析。
>>> record = ('ACME', 50, 123.45, (12, 18, 2012))
>>> name, *_, (*_, year) = record
>>>
>>>
>>>
>>> name
'ACME'
>>> _
[12, 18]
>>>
>>>
>>> year
2012
3. 查找最大或最小的 N 個(gè)元素
heapq
模塊有兩個(gè)函數(shù):nlargest()
和 nsmallest()
可以完美解決這個(gè)問題犀被。
輸出最大和最小的三個(gè)值:
>>> import heapq
>>> nums = [1, 8, 2, 23, 7, -4, 18, 23, 42, 37, 2]
>>> print(heapq.nlargest(3, nums))
[42, 37, 23]
>>> print(heapq.nsmallest(3, nums))
[-4, 1, 2]
兩個(gè)函數(shù)都能接受一個(gè)關(guān)鍵字參數(shù),用于更復(fù)雜的數(shù)據(jù)結(jié)構(gòu)中:
>>> portfolio = [
... {'name': 'IBM', 'shares': 100, 'price': 91.1},
... {'name': 'AAPL', 'shares': 50, 'price': 543.22},
... {'name': 'FB', 'shares': 200, 'price': 21.09},
... {'name': 'HPQ', 'shares': 35, 'price': 31.75},
... {'name': 'YHOO', 'shares': 45, 'price': 16.35},
... {'name': 'ACME', 'shares': 75, 'price': 115.65}
... ]
>>> cheap = heapq.nsmallest(3, portfolio, key=lambda s: s['price'])
>>> expensive = heapq.nlargest(3, portfolio, key=lambda s: s['price'])
>>>
>>> cheap
[{'name': 'YHOO', 'shares': 45, 'price': 16.35}, {'name': 'FB', 'shares': 200, 'price': 21.09}, {'name': 'HPQ', 'shares': 35, 'price': 31.75}]
>>>
>>> expensive
[{'name': 'AAPL', 'shares': 50, 'price': 543.22}, {'name': 'ACME', 'shares': 75, 'price': 115.65}, {'name': 'IBM', 'shares': 100, 'price': 91.1}]
注意點(diǎn)
當(dāng)要查找的元素個(gè)數(shù)相對比較小的時(shí)候外冀,函數(shù)
nlargest()
和nsmallest()
是很合適的寡键。如果你僅僅想查找唯一的最小或最大(N=1)的元素的話,那么使用
min()
和max()
函數(shù)會(huì)更快些雪隧。如果 N 的大小和集合大小接近的時(shí)候西轩,通常先排序這個(gè)集合然后再使用切片操作會(huì)更快點(diǎn) (
sorted(items)[:N]
或者是sorted(items)[-N:]
)。
4. 實(shí)現(xiàn)一個(gè)優(yōu)先級隊(duì)列
import heapq
class PriorityQueue:
def __init__(self):
self._queue = []
self._index = 0
def push(self, item, priority):
heapq.heappush(self._queue, (-priority, self._index, item))
self._index += 1
def pop(self):
return heapq.heappop(self._queue)[-1]
class Item:
def __init__(self, name):
self.name = name
def __repr__(self):
return 'Item({!r})'.format(self.name)
q = PriorityQueue()
q.push(Item('foo'), 1)
q.push(Item('bar'), 5)
q.push(Item('spam'), 4)
q.push(Item('grok'), 1)
q.pop()
q.pop()
q.pop()
q.pop()
在上面代碼中脑沿,隊(duì)列包含了一個(gè) (-priority, index, item)
的元組藕畔。 優(yōu)先級為負(fù)數(shù)的目的是使得元素按照優(yōu)先級從高到低排序。 這個(gè)跟普通的按優(yōu)先級從低到高排序的堆排序恰巧相反庄拇。
對于Item對象是不支持相互比較的:
>>> a=Item('foo')
>>> b=Item('boo')
>>> a > b
Traceback (most recent call last):
File "test.py", line 26, in <module>
a > b
TypeError: '>' not supported between instances of 'Item' and 'Item'
但是使用元組注服,則可以進(jìn)行比較:
>>> class Item:
... def __init__(self, name):
... self.name = name
... def __repr__(self):
... return 'Item({!r})'.format(self.name)
...
>>>
>>> a=(1, Item('foo'))
>>> b=(2, Item('boo'))
>>> print (a > b)
False
5. 字典中的鍵映射多個(gè)值 multidict
一個(gè)字典就是一個(gè)鍵對應(yīng)一個(gè)單值的映射韭邓。如果你想要一個(gè)鍵映射多個(gè)值,那么你就需要將這多個(gè)值放到另外的容器中溶弟, 比如列表或者集合里面女淑。
d = {
'a' : [1, 2, 3],
'b' : [4, 5]
}
e = {
'a' : {1, 2, 3},
'b' : {4, 5}
}
使用 collections
模塊中的 defaultdict
來構(gòu)造一鍵多值的字典:
>>> from collections import defaultdict
>>>
>>> d = defaultdict(list)
>>> d['a'].append(1)
>>> d['a'].append(2)
>>> d['b'].append(4)
>>>
>>> d = defaultdict(set)
>>> d['a'].add(1)
>>> d['a'].add(2)
>>> d['b'].add(4)
>>>
>>> d
defaultdict(<class 'set'>, {'a': {1, 2}, 'b': {4}})
defaultdict
會(huì)自動(dòng)為將要訪問的鍵(就算目前字典中并不存在這樣的鍵)創(chuàng)建映射實(shí)體。
>>> d = defaultdict(set)
>>>
>>>
>>> d['d']
set()
>>> d
defaultdict(<class 'set'>, {'d': set()})
可以通過一個(gè)普通的字典上使用 setdefault()
去除這個(gè)情況:
>>> d = {}
>>> d.setdefault('a', []).append(1)
>>> d.setdefault('a', []).append(2)
>>> d.setdefault('b', []).append(4)
>>>
>>> d
{'a': [1, 2], 'b': [4]}
>>> d['c']
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
KeyError: 'c'
>>>
>>> d['a']
[1, 2]
這種寫法是讓人非常別扭的辜御,因?yàn)樾枰嘈┮淮?code>[]鸭你。
也可以自己實(shí)現(xiàn):
d = {}
for key, value in pairs:
if key not in d:
d[key] = []
d[key].append(value)
但是從Python
提倡的簡潔上來說,沒有defaultdict
簡潔:
d = defaultdict(list)
for key, value in pairs:
d[key].append(value)
6. 字典按順序輸出
為了能控制一個(gè)字典中元素的順序擒权,你可以使用 collections
模塊中的 OrderedDict
類
>>> from collections import OrderedDict
>>>
>>> d = OrderedDict()
>>> d['foo'] = 1
>>> d['bar'] = 2
>>> d['spam'] = 3
>>> d['grok'] = 4
>>>
>>> d
OrderedDict([('foo', 1), ('bar', 2), ('spam', 3), ('grok', 4)])
>>>
>>> for key in d:
... print(key, d[key])
...
foo 1
bar 2
spam 3
grok 4
OrderedDict
內(nèi)部維護(hù)著一個(gè)根據(jù)鍵插入順序排序的雙向鏈表袱巨。每次當(dāng)一個(gè)新的元素插入進(jìn)來的時(shí)候姊途, 它會(huì)被放到鏈表的尾部萧落。
一個(gè) OrderedDict
的大小是一個(gè)普通字典的兩倍胆胰,因?yàn)樗鼉?nèi)部維護(hù)著另外一個(gè)鏈表蝠猬。 大量數(shù)據(jù)時(shí)陕截,需要權(quán)衡效率果元。
7. 字典運(yùn)算
如何在數(shù)據(jù)字典中 執(zhí)行 求最小值丹喻、最大值椒惨、排序贱鄙?
上面我們學(xué)習(xí)的方法為:
使用
heapq
中的nlargest
劝贸、nsmallest
、heapify
完成堆排序逗宁。使用
sorted
函數(shù)映九。使用
min
函數(shù) 和max
函數(shù)
參考股票名和價(jià)格映射字典:
prices = {
'ACME': 45.23,
'AAPL': 612.78,
'IBM': 205.55,
'HPQ': 37.20,
'FB': 10.75
}
7.1 heapq
顯然無法實(shí)現(xiàn)字典排序,無論是根據(jù)key
排序瞎颗,還是根據(jù)value
排序件甥。
>>> heapq.nlargest(1, prices)
['IBM']
>>> heapq.nsmallest(1, prices)
['AAPL']
>>> heapq.heapify(prices)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: heap argument must be a list
7.2 sorted
顯然 sorted
無法實(shí)現(xiàn)對value
的排序,只能對key
進(jìn)行排序并返回排好序的key
列表哼拔,且還需要再次遍歷這個(gè)列表才能獲取value
引有。
>>> sorted(prices)
['AAPL', 'ACME', 'FB', 'HPQ', 'IBM']
7.2 min max
顯然和sorted
是相同的問題,只能對key
進(jìn)行排序倦逐。
>>> min(prices)
'AAPL'
>>>
>>>
>>> max(prices)
'IBM'
方案1 zip:
我們?yōu)榱藢χ颠M(jìn)行操作時(shí)譬正,需要使用zip()
函數(shù)對key
與value
進(jìn)行翻轉(zhuǎn)。
>>> list(zip(prices.values(), prices.keys()))
[(45.23, 'ACME'), (612.78, 'AAPL'), (205.55, 'IBM'), (37.2, 'HPQ'), (10.75, 'FB')]
>>>
>>>
>>> min(zip(prices.values(), prices.keys()))
(10.75, 'FB')
>>>
>>>
>>> max(zip(prices.values(), prices.keys()))
(612.78, 'AAPL')
>>>
>>>
>>> sorted(zip(prices.values(), prices.keys()))
[(10.75, 'FB'), (37.2, 'HPQ'), (45.23, 'ACME'), (205.55, 'IBM'), (612.78, 'AAPL')]
需要注意的是 zip() 函數(shù)創(chuàng)建的是一個(gè)只能訪問一次的迭代器檬姥。
>>> prices_and_names = zip(prices.values(), prices.keys())
>>> print(min(prices_and_names)) # OK
(10.75, 'FB')
>>> print(max(prices_and_names))
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: max() arg is an empty sequence
方案2 min + values max + values
直接輸出最大或者最小values
>>> min(prices.values()) # Returns 10.75
10.75
>>> max(prices.values()) # Returns 612.78
612.78
輸出最大或者最小的value
對應(yīng)的key
>>> min(prices, key=lambda k: prices[k])
'FB'
>>> max(prices, key=lambda k: prices[k])
'AAPL'
8. 查找兩字典的相同點(diǎn)
怎樣在兩個(gè)字典中尋尋找相同點(diǎn)(比如相同的鍵曾我、相同的值等等)?
a = {
'x' : 1,
'y' : 2,
'z' : 3
}
b = {
'w' : 10,
'x' : 11,
'y' : 2
}
最直接的想法便是遍歷a
健民,然后檢查b
抒巢。
python其實(shí)更加簡單方便
相同的key
>>> a.keys() & b.keys()
{'y', 'x'}
a
中有,b
中沒有的key
>>> a.keys() - b.keys()
{'z'}
相同的元素
>>> a.items() & b.items()
{('y', 2)}
兩個(gè)字典的合集
>>> a.items() | b.items()
{('x', 11), ('z', 3), ('y', 2), ('w', 10), ('x', 1)}
我們可以使用以上的操作秉犹,來完成修改或者過濾字典元素虐秦。
>>> c = {key:a[key] for key in a.keys() - {'z', 'w'}}
>>>
>>>
>>> c
{'y': 2, 'x': 1}
一個(gè)字典就是一個(gè)鍵集合與值集合的映射關(guān)系平酿。 字典的 keys()
方法返回一個(gè)展現(xiàn)鍵集合的鍵視圖對象。 鍵視圖的一個(gè)很少被了解的特性就是它們也支持集合操作悦陋,比如集合并、交筑辨、差運(yùn)算俺驶。 所以,如果你想對集合的鍵執(zhí)行一些普通的集合操作棍辕,可以直接使用鍵視圖對象而不用先將它們轉(zhuǎn)換成一個(gè) set
暮现。
>>> type(a.keys())
<class 'dict_keys'>
>>>
>>>
>>> type(a.keys() & b.keys())
<class 'set'>
字典的 items()
方法返回一個(gè)包含 (鍵,值) 對的元素視圖對象楚昭。 這個(gè)對象同樣也支持集合操作栖袋,并且可以被用來查找兩個(gè)字典有哪些相同的鍵值對。
>>> type(a.items())
<class 'dict_items'>
>>>
>>>
>>> type(a.items() & b.items())
<class 'set'>
盡管字典的 values()
方法也是類似抚太,但是它并不支持這里介紹的集合操作塘幅。 某種程度上是因?yàn)橹狄晥D不能保證所有的值互不相同,這樣會(huì)導(dǎo)致某些集合操作會(huì)出現(xiàn)問題尿贫。 不過电媳,如果你硬要在值上面執(zhí)行這些集合操作的話,你可以先將值集合轉(zhuǎn)換成 set庆亡,然后再執(zhí)行集合運(yùn)算就行了匾乓。
>>>
>>> type(a.values())
<class 'dict_values'>
>>>
>>>
>>> a.values() & b.values()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unsupported operand type(s) for &: 'dict_values' and 'dict_values'
>>>
>>>
>>> set(a.values()) & set(b.values())
{2}
9. 刪除序列相同元素并保持順序
怎樣在一個(gè)序列上面保持元素順序的同時(shí)消除重復(fù)的值?
如果序列上的值都是 hashable
類型又谋,那么可以很簡單的利用集合或者生成器來解決這個(gè)問題拼缝。
什么是 hashable
類型?
An object is
hashable
if it has a hash value which never changes during its lifetime (it needs a__hash__()
method), and can be compared to other objects (it needs an__eq__()
method). Hashable objects which compare equal must have the same hash value. Hashability makes an object usable as a dictionary key and a set member, because these data structures use the hash value internally.
如果一個(gè)對象在其生命周期內(nèi)有一個(gè)固定不變的哈希值 (這需要
__hash__()
方法) 彰亥,且可以與其他對象進(jìn)行比較操作 (這需要__eq__()
方法) 咧七,那么這個(gè)對象就是可哈希對象 (hashable
) ∈@ⅲ可哈希對象必須有相同的哈希值才算作相等猪叙。 由于字典 (dict
) 的鍵 (key
) 和集合 (set
) 內(nèi)部使用到了哈希值,所以只有可哈希 (hashable
) 對象才能被用作字典的鍵和集合的元素仁卷。 所有python
內(nèi)置的不可變對象都是可哈希的穴翩,同時(shí),可變?nèi)萜?(比如:列表 (list
) 或者字典 (dict
) ) 都是不可哈希的锦积。用戶自定義的類的實(shí)例默認(rèn)情況下都是可哈希的芒帕;它們跟其它對象都不相等 (除了它們自己) ,它們的哈希值來自id()
方法丰介。
>>>
>>> def dedupe(items):
... seen = set()
... for item in items:
... if item not in seen:
... yield item
... seen.add(item)
... return items
...
>>> a = [1, 5, 2, 1, 9, 1, 5, 10]
>>>
>>> list(dedupe(a))
[1, 5, 2, 9, 10]
這個(gè)方法僅僅在序列中元素為 hashable
的時(shí)候才管用背蟆。 如果你想消除元素不可哈希(比如 dict
類型)的序列中重復(fù)元素的話鉴分,你需要將上述代碼稍微改變一下,就像這樣:
>>> def dedupe(items, key=None):
... seen = set()
... for item in items:
... val = item if key is None else key(item)
... if val not in seen:
... yield item
... seen.add(val)
... return items
...
>>>
>>> a = [ {'x':1, 'y':2}, {'x':1, 'y':3}, {'x':1, 'y':2}, {'x':2, 'y':4}]
>>>
>>> list(dedupe(a, key=lambda d: (d['x'],d['y'])))
[{'x': 1, 'y': 2}, {'x': 1, 'y': 3}, {'x': 2, 'y': 4}]
>>>
>>>
>>> list(dedupe(a, key=lambda d: d['x']))
[{'x': 1, 'y': 2}, {'x': 2, 'y': 4}]
如果你僅僅就是想消除重復(fù)元素而不用維持順序的話带膀,通持菊洌可以簡單的構(gòu)造一個(gè)集合
>>> a=[1, 5, 2, 1, 9, 1, 5, 10]
>>> list(set(a))
[1, 2, 5, 9, 10]
如果我們想讀取文件并排除掉重復(fù)行,也可以使用上面的方法
with open(somefile,'r') as f:
for line in dedupe(f):
...
10. 命名切片
假定你有一段代碼要從一個(gè)記錄字符串中幾個(gè)固定位置提取出特定的數(shù)據(jù)字段(比如文件或類似格式):
>>> record = '....................100 .......513.25 ..........'
>>> cost = int(record[20:23]) * float(record[31:37])
>>> cost
51325.0
我們需要命名切片 slice
slice
有三個(gè)屬性垛叨,start
, stop
, step
伦糯。在創(chuàng)建構(gòu)造函數(shù)時(shí),可以適時(shí)忽略嗽元。
創(chuàng)建切片
>>> a=slice(10) #stop為10, step默認(rèn)為1的分片
>>> a
slice(None, 10, None)
>>> a=slice(0, 10) # start為1敛纲, stop為10, step默認(rèn)為1的分片
>>> a
slice(0, 10, None)
>>> a=slice(0, 10, 2) # start為1, stop為10, step為2的分片
>>> a
slice(0, 10, 2)
示例:
>>> SHARES = slice(20, 23)
>>> PRICE = slice(31, 37)
>>> cost = int(record[SHARES]) * float(record[PRICE])
>>> cost
51325.0
這樣你避免了大量無法理解的硬編碼下標(biāo)剂癌,使得你的代碼更加清晰可讀了淤翔。
內(nèi)置的 slice() 函數(shù)創(chuàng)建了一個(gè)切片對象,可以被用在任何切片允許使用的地方佩谷。
>>> items = [0, 1, 2, 3, 4, 5, 6]
>>> a = slice(2, 4)
>>> items[a]
[2, 3]
>>> items[a] = [10,11]
>>> items[a]
[10, 11]
>>> items
[0, 1, 10, 11, 4, 5, 6]
如果你有一個(gè)切片對象 a
旁壮,你可以分別調(diào)用它的 a.start
, a.stop
, a.step
屬性來獲取更多的信息。比如:
>>> a = slice(5, 50, 2)
>>> a.start
5
>>> a.stop
50
>>> a.step
2
>>>
我們也可以調(diào)用切片的 indices(size)
方法將它映射到一個(gè)確定大小的序列上琳要, 這個(gè)方法返回一個(gè)三元組 ( start
, stop
, step
) 寡具,所有值都會(huì)被合適的縮小以滿足邊界限制, 從而使用的時(shí)候避免出現(xiàn) IndexError
異常
>>> items = [0, 1, 2, 3, 4, 5, 6]
>>> a=slice(0,0)
>>> type(a)
<class 'slice'>
>>> b=a.indices(len(items))
>>> b
(0, 0, 1)
>>> type(b)
<class 'tuple'>
11. 序列中出現(xiàn)次數(shù)最多的元素
怎樣找出一個(gè)序列中出現(xiàn)次數(shù)最多的元素呢稚补?
我們可能需要collections.Counter
童叠, Counter
對象可以接受任意的由可哈希(hashable
)元素構(gòu)成的序列對象。 在底層實(shí)現(xiàn)上课幕,一個(gè) Counter
對象就是一個(gè)字典厦坛,將元素映射到它出現(xiàn)的次數(shù)上。
from collections import Counter
>>> words = [
... 'look', 'into', 'my', 'eyes', 'look', 'into', 'my', 'eyes',
... 'the', 'eyes', 'the', 'eyes', 'the', 'eyes', 'not', 'around', 'the',
... 'eyes', "don't", 'look', 'around', 'the', 'eyes', 'look', 'into',
... 'my', 'eyes', "you're", 'under'
... ]
>>> word_counts = Counter(words)
>>>
>>> word_counts
Counter({'eyes': 8, 'the': 5, 'look': 4, 'into': 3, 'my': 3, 'around': 2, 'not': 1, "don't": 1, "you're": 1, 'under': 1})
>>>
>>> type(word_counts)
<class 'collections.Counter'>
>>>
>>>
>>> dir(word_counts)
['__add__', '__and__', '__class__', '__contains__', '__delattr__', '__delitem__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__gt__', '__hash__', '__iadd__', '__iand__', '__init__', '__init_subclass__', '__ior__', '__isub__', '__iter__', '__le__', '__len__', '__lt__', '__missing__', '__module__', '__ne__', '__neg__', '__new__', '__or__', '__pos__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__setitem__', '__sizeof__', '__str__', '__sub__', '__subclasshook__', '__weakref__', '_keep_positive', 'clear', 'copy', 'elements', 'fromkeys', 'get', 'items', 'keys', 'most_common', 'pop', 'popitem', 'setdefault', 'subtract', 'update', 'values']
>>>
>>> word_counts['not']
1
>>> word_counts['eyes']
8
>>>
我們也可以手動(dòng)添加:
>>> morewords = ['why','are','you','not','looking','in','my','eyes']
>>> for word in morewords:
... word_counts[word] += 1
...
>>> word_counts['eyes']
>>> 9
只不過 Counter
的內(nèi)部提供了 update
的方法:
>>> word_counts.update(morewords)
>>> word_counts['eyes']
>>> 10
由于Counter
實(shí)現(xiàn)了 hashable
乍惊, 因此可以用于運(yùn)算操作杜秸。
>>> a = Counter(words)
>>> b = Counter(morewords)
>>> a
Counter({'eyes': 8, 'the': 5, 'look': 4, 'into': 3, 'my': 3, 'around': 2, 'not': 1, "don't": 1, "you're": 1, 'under': 1})
>>> b
Counter({'why': 1, 'are': 1, 'you': 1, 'not': 1, 'looking': 1, 'in': 1, 'my': 1, 'eyes': 1})
>>>
>>>
>>> a | b
Counter({'eyes': 8, 'the': 5, 'look': 4, 'into': 3, 'my': 3, 'around': 2, 'not': 1, "don't": 1, "you're": 1, 'under': 1, 'why': 1, 'are': 1, 'you': 1, 'looking': 1, 'in': 1})
>>>
>>> a + b
Counter({'eyes': 9, 'the': 5, 'look': 4, 'my': 4, 'into': 3, 'not': 2, 'around': 2, "don't": 1, "you're": 1, 'under': 1, 'why': 1, 'are': 1, 'you': 1, 'looking': 1, 'in': 1})
>>>
>>>
>>>
>>> a - b
Counter({'eyes': 7, 'the': 5, 'look': 4, 'into': 3, 'my': 2, 'around': 2, "don't": 1, "you're": 1, 'under': 1})
>>>
>>> a & b
Counter({'my': 1, 'eyes': 1, 'not': 1})
因此,Counter
這個(gè)特性會(huì)在很多場合使用润绎,比如合并統(tǒng)計(jì)數(shù)據(jù)撬碟,制表等等場合。
12. 通過某個(gè)關(guān)鍵字排序一個(gè)字典列表
你有一個(gè)字典列表莉撇,你想根據(jù)某個(gè)或某幾個(gè)字典字段來排序這個(gè)列表
使用 operator
模塊的 itemgetter
函數(shù)呢蛤。
>>> from operator import itemgetter
>>>
>>> rows = [
... {'fname': 'Brian', 'lname': 'Jones', 'uid': 1003},
... {'fname': 'David', 'lname': 'Beazley', 'uid': 1002},
... {'fname': 'John', 'lname': 'Cleese', 'uid': 1001},
... {'fname': 'Big', 'lname': 'Jones', 'uid': 1004}
... ]
>>>
>>>
>>> rows_by_fname = sorted(rows, key=itemgetter('fname'))
>>> rows_by_uid = sorted(rows, key=itemgetter('uid'))
>>> rows_by_all = sorted(rows, key=itemgetter('fname', 'uid'))
>>>
>>> rows_by_fname
[{'fname': 'Big', 'lname': 'Jones', 'uid': 1004}, {'fname': 'Brian', 'lname': 'Jones', 'uid': 1003}, {'fname': 'David', 'lname': 'Beazley', 'uid': 1002}, {'fname': 'John', 'lname': 'Cleese', 'uid': 1001}]
>>>
>>> rows_by_uid
[{'fname': 'John', 'lname': 'Cleese', 'uid': 1001}, {'fname': 'David', 'lname': 'Beazley', 'uid': 1002}, {'fname': 'Brian', 'lname': 'Jones', 'uid': 1003}, {'fname': 'Big', 'lname': 'Jones', 'uid': 1004}]
>>>
>>> rows_by_all
[{'fname': 'Big', 'lname': 'Jones', 'uid': 1004}, {'fname': 'Brian', 'lname': 'Jones', 'uid': 1003}, {'fname': 'David', 'lname': 'Beazley', 'uid': 1002}, {'fname': 'John', 'lname': 'Cleese', 'uid': 1001}]
同樣,itemgetter()
有時(shí)候也可以用 lambda
表達(dá)式代替棍郎,但是沒有itemgetter()
效率高其障。比如:
>>> rows_by_fname = sorted(rows, key=lambda r: r['fname'])
>>> rows_by_lfname = sorted(rows, key=lambda r: (r['lname'],r['fname']))
>>>
>>>
>>>
>>> rows_by_lfname
[{'fname': 'David', 'lname': 'Beazley', 'uid': 1002}, {'fname': 'John', 'lname': 'Cleese', 'uid': 1001}, {'fname': 'Big', 'lname': 'Jones', 'uid': 1004}, {'fname': 'Brian', 'lname': 'Jones', 'uid': 1003}]
>>> rows_by_fname
[{'fname': 'Big', 'lname': 'Jones', 'uid': 1004}, {'fname': 'Brian', 'lname': 'Jones', 'uid': 1003}, {'fname': 'David', 'lname': 'Beazley', 'uid': 1002}, {'fname': 'John', 'lname': 'Cleese', 'uid': 1001}]
最后,不要忘了這節(jié)中展示的技術(shù)也同樣適用于 min() 和 max() 等函數(shù)
>>> min(rows, key=itemgetter('uid'))
{'fname': 'John', 'lname': 'Cleese', 'uid': 1001}
>>> max(rows, key=itemgetter('uid'))
{'fname': 'Big', 'lname': 'Jones', 'uid': 1004}
>>>
同樣需要注意的是涂佃,由于 dict
不是 hashable
励翼。所以不能使用 min
蜈敢、max
、sorted
汽抚。但是tuple
抓狭、set
是hasable
,所以我們可以通過 lambda
和 itemgetter
來完成對兩者的排序殊橙。
>>> rows = [
... {'fname': 'Brian', 'lname': 'Jones', 'uid': 1003},
... {'fname': 'David', 'lname': 'Beazley', 'uid': 1002},
... {'fname': 'John', 'lname': 'Cleese', 'uid': 1001},
... {'fname': 'Big', 'lname': 'Jones', 'uid': 1004}
... ]
>>>
>>> min(rows)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: '<' not supported between instances of 'dict' and 'dict'
>>>
>>> max(rows)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: '>' not supported between instances of 'dict' and 'dict'
>>>
>>> sorted(rows)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: '<' not supported between instances of 'dict' and 'dict'
>>>
>>> min(rows, key=lambda r:(r['fname']))
{'fname': 'Big', 'lname': 'Jones', 'uid': 1004}
>>>
>>> max(rows, key=lambda r:(r['fname']))
{'fname': 'John', 'lname': 'Cleese', 'uid': 1001}
>>>
>>> sorted(rows, key=lambda r:(r['fname']))
[{'fname': 'Big', 'lname': 'Jones', 'uid': 1004}, {'fname': 'Brian', 'lname': 'Jones', 'uid': 1003}, {'fname': 'David', 'lname': 'Beazley', 'uid': 1002}, {'fname': 'John', 'lname': 'Cleese', 'uid': 1001}]
>>>
13. 排序不支持原生比較的對象
你想排序類型相同的對象辐宾,但是他們不支持原生的比較操作。
上一節(jié)我們知道sorted
膨蛮、min
、max
季研、heapq.nsmallest
敞葛、heapq.nlargest
函數(shù)有一個(gè)關(guān)鍵字參數(shù) key
,可以傳入一個(gè)callable
對象給它与涡。
這個(gè) callable
對象對每個(gè)傳入的對象返回一個(gè)值惹谐,這個(gè)值會(huì)被用來排序這些對象。而這個(gè)callable對象可以是我們使用lambda
自定義對象驼卖,或者使用from operator import attrgetter
或者from operator import itemgetter
氨肌。
本章第3節(jié)、第4節(jié)酌畜、第7節(jié)怎囚、第12節(jié)都在講如何排序。
13.1 hashable
排序
當(dāng)裝有hashable
類型的list
桥胞、tuple
恳守、set
我們可以使用任意的排序方式進(jìn)行排序。
list排序
>>> letters=['a', 'b', 'c', 'd', 'z', 'g']
>>> sorted(letters)
['a', 'b', 'c', 'd', 'g', 'z']
>>>
>>> min(letters)
'a'
>>> max(letters)
'z'
>>>
>>> import heapq
>>>
>>> heapq.nsmallest(1, letters)
['a']
>>> heapq.nlargest(1, letters)
['z']
>>> sorted(letters)[0]
'a'
>>> sorted(letters)[len(letters) -1]
'z'
tuple排序
>>> letters=('a', 'b', 'c', 'd', 'z', 'g')
>>> sorted(letters)
['a', 'b', 'c', 'd', 'g', 'z']
>>> type(sorted(letters))
<class 'list'>
>>> min(letters)
'a'
>>> max(letters)
'z'
>>> import heapq
>>>
>>> heapq.nsmallest(1, letters)
['a']
>>> heapq.nlargest(1, letters)
['z']
>>> sorted(letters)[0]
'a'
>>> sorted(letters)[len(letters) -1]
'z'
set排序
>>> letters=('a', 'b', 'c', 'd', 'z', 'g')
>>> letters=set(letters)
>>> sorted(letters)
['a', 'b', 'c', 'd', 'g', 'z']
>>> type(sorted(letters))
<class 'list'>
>>> min(letters)
'a'
>>> max(letters)
'z'
>>> import heapq
>>>
>>> heapq.nsmallest(1, letters)
['a']
>>> heapq.nlargest(1, letters)
['z']
>>> sorted(letters)[0]
'a'
>>> sorted(letters)[len(letters) -1]
'z'
13.2 非hashable 排序
我們知道dict
贩虾、自定義對象是 非hashable
的催烘。
裝有dict元素的列表
>>> import heapq
>>> portfolio = [
... {'name': 'IBM', 'shares': 100, 'price': 91.1},
... {'name': 'AAPL', 'shares': 50, 'price': 543.22},
... {'name': 'FB', 'shares': 200, 'price': 21.09},
... {'name': 'HPQ', 'shares': 35, 'price': 31.75},
... {'name': 'YHOO', 'shares': 45, 'price': 16.35},
... {'name': 'ACME', 'shares': 75, 'price': 115.65}
... ]
>>> heapq.nsmallest(3, portfolio, key=lambda s: s['price'])
[{'name': 'YHOO', 'shares': 45, 'price': 16.35}, {'name': 'FB', 'shares': 200, 'price': 21.09}, {'name': 'HPQ', 'shares': 35, 'price': 31.75}]
>>>
>>> heapq.nlargest(3, portfolio, key=lambda s: s['price'])
[{'name': 'AAPL', 'shares': 50, 'price': 543.22}, {'name': 'ACME', 'shares': 75, 'price': 115.65}, {'name': 'IBM', 'shares': 100, 'price': 91.1}]
>>>
>>> sorted(portfolio, key=lambda n: (n['name']))
[{'name': 'AAPL', 'shares': 50, 'price': 543.22}, {'name': 'ACME', 'shares': 75, 'price': 115.65}, {'name': 'FB', 'shares': 200, 'price': 21.09}, {'name': 'HPQ', 'shares': 35, 'price': 31.75}, {'name': 'IBM', 'shares': 100, 'price': 91.1}, {'name': 'YHOO', 'shares': 45, 'price': 16.35}]
>>>
>>> sorted(portfolio, key=lambda n: (n['shares'], n['price']))
[{'name': 'HPQ', 'shares': 35, 'price': 31.75}, {'name': 'YHOO', 'shares': 45, 'price': 16.35}, {'name': 'AAPL', 'shares': 50, 'price': 543.22}, {'name': 'ACME', 'shares': 75, 'price': 115.65}, {'name': 'IBM', 'shares': 100, 'price': 91.1}, {'name': 'FB', 'shares': 200, 'price': 21.09}]
>>>
>>> min(portfolio, key=lambda n: (n['name']))
{'name': 'AAPL', 'shares': 50, 'price': 543.22}
>>>
>>> max(portfolio, key=lambda n: (n['name']))
{'name': 'YHOO', 'shares': 45, 'price': 16.35}
>>>
>>> from operator import itemgetter
>>>
>>> min(portfolio, key=itemgetter('name'))
{'name': 'AAPL', 'shares': 50, 'price': 543.22}
>>>
>>> max(portfolio, key=itemgetter('name'))
{'name': 'YHOO', 'shares': 45, 'price': 16.35}
>>>
>>> sorted(portfolio, key=itemgetter('name'))
[{'name': 'AAPL', 'shares': 50, 'price': 543.22}, {'name': 'ACME', 'shares': 75, 'price': 115.65}, {'name': 'FB', 'shares': 200, 'price': 21.09}, {'name': 'HPQ', 'shares': 35, 'price': 31.75}, {'name': 'IBM', 'shares': 100, 'price': 91.1}, {'name': 'YHOO', 'shares': 45, 'price': 16.35}]
dict
>>> prices = {
... 'ACME': 45.23,
... 'AAPL': 612.78,
... 'IBM': 205.55,
... 'HPQ': 37.20,
... 'FB': 10.75
... }
>>> sorted(prices)
['AAPL', 'ACME', 'FB', 'HPQ', 'IBM']
>>>
>>> min(prices)
'AAPL'
>>>
>>> max(prices)
'IBM'
>>> sorted(prices, key=lambda n : prices[n])
['FB', 'HPQ', 'ACME', 'IBM', 'AAPL']
>>>
>>> min(prices, key=lambda n : prices[n])
'FB'
>>> max(prices, key=lambda n : prices[n])
'AAPL'
>>> heapq.nsmallest(1, prices)
['AAPL']
>>>
>>> heapq.nlargest(1, prices)
['IBM']
>>>
>>> min(zip(prices.values(), prices.keys()))
(10.75, 'FB')
>>>
>>> max(zip(prices.values(), prices.keys()))
(612.78, 'AAPL')
>>> sorted(zip(prices.values(), prices.keys()))
[(10.75, 'FB'), (37.2, 'HPQ'), (45.23, 'ACME'), (205.55, 'IBM'), (612.78, 'AAPL')]
>>>
>>> min(prices.values())
10.75
>>>
>>> max(prices.values())
612.78
>>> sorted(prices.values())
[10.75, 37.2, 45.23, 205.55, 612.78]
自定義對象
class User:
def __init__(self, user_id):
self.user_id = user_id
def __repr__(self):
return 'User({})'.format(self.user_id)
>>> users = [User(23), User(3), User(99)]
>>>
>>> sorted(users, key=lambda n: (n.user_id))
[User(3), User(23), User(99)]
>>> min(users, key=lambda n: (n.user_id))
User(3)
>>> max(users, key=lambda n: (n.user_id))
User(99)
>>>
>>> from operator import attrgetter
>>>
>>> sorted(users, key=attrgetter('user_id'))
[User(3), User(23), User(99)]
>>> min(users, key=attrgetter('user_id'))
User(3)
>>> max(users, key=attrgetter('user_id'))
User(99)
14. 通過某個(gè)字段將記錄分組
我們可以使用 itertools.groupby()
對 字典或者序列進(jìn)行分組。
groupby()
僅僅檢查連續(xù)的元素缎罢,如果事先并沒有排序完成的話伊群,分組函數(shù)將得不到想要的結(jié)果。
>>> rows = [
... {'address': '5412 N CLARK', 'date': '07/01/2012'},
... {'address': '5148 N CLARK', 'date': '07/04/2012'},
... {'address': '5800 E 58TH', 'date': '07/02/2012'},
... {'address': '2122 N CLARK', 'date': '07/03/2012'},
... {'address': '5645 N RAVENSWOOD', 'date': '07/02/2012'},
... {'address': '1060 W ADDISON', 'date': '07/02/2012'},
... {'address': '4801 N BROADWAY', 'date': '07/01/2012'},
... {'address': '1039 W GRANVILLE', 'date': '07/04/2012'},
... ]
>>>
>>> # Sort by the desired field first
... rows.sort(key=itemgetter('date'))
>>> # Iterate in groups
... for date, items in groupby(rows, key=itemgetter('date')):
... print(date)
... for i in items:
... print(' ', i)
>>>
07/01/2012
{'address': '5412 N CLARK', 'date': '07/01/2012'}
{'address': '4801 N BROADWAY', 'date': '07/01/2012'}
07/02/2012
{'address': '5800 E 58TH', 'date': '07/02/2012'}
{'address': '5645 N RAVENSWOOD', 'date': '07/02/2012'}
{'address': '1060 W ADDISON', 'date': '07/02/2012'}
07/03/2012
{'address': '2122 N CLARK', 'date': '07/03/2012'}
07/04/2012
{'address': '5148 N CLARK', 'date': '07/04/2012'}
{'address': '1039 W GRANVILLE', 'date': '07/04/2012'}
如果不想進(jìn)行排序策精,僅僅是想根據(jù)date
對數(shù)據(jù)進(jìn)行分組舰始,且隨機(jī)訪問,那么歡迎使用defaultdict()
>>> from collections import defaultdict
>>> rows_by_date = defaultdict(list)
>>> for row in rows:
... rows_by_date[row['date']].append(row)
>>>
>>> rows_by_date['07/04/2012']
[{'address': '5148 N CLARK', 'date': '07/04/2012'}, {'address': '1039 W GRANVILLE', 'date': '07/04/2012'}]
15. 過濾序列元素
你有一個(gè)數(shù)據(jù)序列蛮寂,想利用一些規(guī)則從中提取出需要的值或者是縮短序列
使用列表推導(dǎo)
>>> mylist = [1, 4, -5, 10, -7, 2, 3, -1]
>>> [n for n in mylist if n > 0]
[1, 4, 10, 2, 3]
>>> t=[n for n in mylist if n < 0]
>>>
>>> t
[-5, -7, -1]
>>>
>>> type(t)
<class 'list'>
列表推導(dǎo)的一個(gè)潛在缺陷就是如果要過濾的列表過大產(chǎn)生一個(gè)非常大的結(jié)果集蔽午,占用大量內(nèi)存。所以建議使用生成器表達(dá)式迭代
生成器表達(dá)式迭代
>>> pos = (n for n in mylist if n > 0)
>>>
>>> type(pos)
<class 'generator'>
>>> for x in pos:
... print(x)
...
1
4
10
2
3
如果過濾條件過于復(fù)雜酬蹋,那么可以把過濾條件放到一個(gè)函數(shù)中及老,并使用filter()
>>> values = ['1', '2', '-3', '-', '4', 'N/A', '5']
>>> def is_int(val):
... try:
... x = int(val)
... return True
... except ValueError:
... return False
...
>>> n=filter(is_int, values)
>>> type(n)
<class 'filter'>
>>> ivals = list(n)
>>>
>>> ivals
['1', '2', '-3', '4', '5']
filter
類是一個(gè)迭代器抽莱,因此如果我們需要變成一個(gè)列表時(shí)可以使用list()
。如果我們需要遍歷時(shí)骄恶,請直接使用:
>>> n=filter(is_int, values)
>>> for x in n:
... print(x)
過濾的同時(shí)修改數(shù)據(jù)
生成器表達(dá)式迭代和列表推導(dǎo)能夠干很多很多有意思的事情食铐,比如在過濾的同時(shí)完成對數(shù)據(jù)的進(jìn)一步改造:
將mylist
的中的數(shù)字全部平方,然后過濾丟棄僧鲁。
>>> mylist = [1, 4, -5, 10, -7, 2, 3, -1]
>>> import math
>>> [math.sqrt(n) for n in mylist if n > 0]
[1.0, 2.0, 3.1622776601683795, 1.4142135623730951, 1.7320508075688772]
將小于0的數(shù)用0代替虐呻,而不是丟棄掉。
>>> mylist = [1, 4, -5, 10, -7, 2, 3, -1]
>>> [n if n > 0 else 0 for n in mylist]
[1, 4, 0, 10, 0, 2, 3, 0]
itertools.compress()
itertools.compress()
以一個(gè) iterable
對象和一個(gè)相對應(yīng)的 Boolean
選擇器序列作為輸入?yún)?shù)寞秃。 然后輸出 iterable
對象中對應(yīng)選擇器為 True
的元素斟叼。
>>> 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] #`Boolean` 選擇器序列
>>> more5
[False, False, True, False, False, True, True, False]
>>>
>>> compress=compress(addresses, more5)
>>> compress
<itertools.compress object at 0x1022b49b0>
>>>
>>> list(compress)
['5800 E 58TH', '1060 W ADDISON', '4801 N BROADWAY']
>>>
需要我們先創(chuàng)建Boolean
選擇器序列,然后才能使用春寿。
16. 從字典中提取子集
字典推導(dǎo)
字典推導(dǎo)能夠完成絕大多數(shù)的需求朗涩,并且速度更快。
>>> 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}
... tech_names = {'AAPL', 'IBM', 'HPQ', 'MSFT'}
>>> p2 = {key: value for key, value in prices.items() if key in tech_names}
>>> p1
{'AAPL': 612.78, 'IBM': 205.55}
>>>
>>> p2
{'AAPL': 612.78, 'IBM': 205.55, 'HPQ': 37.2}
dict() + 元組
>>> p1 = dict((key, value) for key, value in prices.items() if value > 200)
>>>
>>> p1
{'AAPL': 612.78, 'IBM': 205.55}
17. 映射名稱到序列元素
當(dāng)我們從數(shù)據(jù)庫中讀出一行數(shù)據(jù)時(shí)绑改,返回的是一個(gè)元組谢床,我們需要通過下標(biāo)來查找我們想要的字段,這樣的代碼是不可讀的厘线。
collections.namedtuple()
collections.namedtuple()
识腿,可以稱為命名元組, 可以通過一個(gè)存放對應(yīng)key
的元組造壮,來解決映射的問題渡讼。
>>> 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'
>>> type(sub)
<class '__main__.Subscriber'>
namedtuple
看起來想一個(gè)簡單對象,但是它卻支持所有的普通元組操作费薄。
>>> list(sub)
['jonesy@example.com', '2012-10-19']
>>>
>>> len(sub)
2
>>> sub[1]
'2012-10-19'
>>>
>>> addr, joined = sub
>>> addr
'jonesy@example.com'
>>> joined
'2012-10-19'
命名元組不可修改
>>> sub.addr='11@qq.com'
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: can't set attribute
如果非要進(jìn)行修改硝全,那么請使用 _replace()
方法, 但是它會(huì)創(chuàng)建一個(gè)全新的命名元組楞抡。
>>> newSub=sub._replace(addr='11@qq.com')
>>> newSub
Subscriber(addr='11@qq.com', joined='2012-10-19')
另外需要注意的是伟众,命名元組的另一個(gè)用途就是替代只讀字典的,因?yàn)樽值浯鎯?chǔ)需要更多的內(nèi)存空間召廷。 如果你需要構(gòu)建一個(gè)非常大的包含字典的數(shù)據(jù)結(jié)構(gòu)凳厢,那么使用命名元組會(huì)更加高效。
_replace()
_replace()
可以完成根據(jù)你的原始序列竞慢,來填充命名元組先紫。
>>> 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)
18. 轉(zhuǎn)換并同時(shí)計(jì)算數(shù)據(jù)
你需要在數(shù)據(jù)序列上執(zhí)行聚集函數(shù)(比如 sum() , min() , max() )之前,需要轉(zhuǎn)換或者過濾數(shù)據(jù)筹煮。
優(yōu)雅的辦法就是 生成器表達(dá)式遮精,也是我們必須第一個(gè)想到的。
>>> nums = [1, 2, 3, 4, 5]
>>> s = sum(x * x for x in nums)
>>> s
55
>>> s=sum(x for x in nums if x > 3)
>>> s
9
>>> import os
>>> files = os.listdir('/Users/faris/Desktop')
>>> if any(name.endswith('.py') for name in files):
... print('There be python!')
... else:
... print('Sorry, no python.')
There be python!
19. 合并多個(gè)字典或映射
如果我們有兩個(gè)字典a
、b
本冲。我們需要查找一個(gè)值准脂,如果a
中沒有,然后再去b
中找檬洞。
collections. ChainMap 會(huì)將多個(gè)字典邏輯順序合并狸膏。
>>> a = {'x': 1, 'z': 3 }
>>> b = {'y': 2, 'z': 4 }
>>>
>>> from collections import ChainMap
>>> c = ChainMap(a,b)
>>> print(c['x'])
1
>>> print(c['y'])
2
>>> print(c['z']) 打印的是a中的值,而不是b中的值
3
如果出現(xiàn)重復(fù)鍵添怔,那么第一次出現(xiàn)的映射值會(huì)被返回湾戳。 因此,例子程序中的 c['z']
總是會(huì)返回字典 a
中對應(yīng)的值广料,而不是 b
中對應(yīng)的值砾脑。
>>> len(c)
3
>>> c.keys()
KeysView(ChainMap({'x': 1, 'z': 3}, {'y': 2, 'z': 4}))
>>>
>>> c.values()
ValuesView(ChainMap({'x': 1, 'z': 3}, {'y': 2, 'z': 4}))
>>>
>>> list(c.keys())
['z', 'x', 'y']
>>>
>>> list(c.values())
[3, 1, 2]
對于字典的更新或刪除操作總是影響的是列表中第一個(gè)字典。
>>> c['z'] = 10
>>> c['w'] = 40
>>> del c['x']
>>> a
{'w': 40, 'z': 10}
>>> del c['y']
Traceback (most recent call last):
...
KeyError: "Key not found in the first mapping: 'y'"
>>>
如果你想物理合并艾杏,那么請使用dict.update()
拦止,但是它會(huì)重新創(chuàng)建一個(gè)新的字典,并且對新字典的更新不會(huì)反應(yīng)在舊字典糜颠,對舊字典的更新也不會(huì)反應(yīng)在新字典上。
>>> a = {'x': 1, 'z': 3 }
>>> b = {'y': 2, 'z': 4 }
>>>
>>> merged = dict(b)
>>>
>>> merged
{'y': 2, 'z': 4}
>>> merged.update(a)
>>>
>>> merged
{'y': 2, 'z': 3, 'x': 1}
>>>
>>> a
{'x': 1, 'z': 3}
>>>
>>> b
{'y': 2, 'z': 4}