玩轉python字典與列表(中)

dwzb發表於2018-05-26

本文首發於知乎

本文包括如下幾個部分

  • 字典鍵值互換
  • 統計頻數
  • 從字典中提取資訊
  • 鍵值轉換

字典鍵值互換

值唯一的情況

d = {'a': 1, 'b': 2}
{v: k for k, v in d.items()}
# {1: 'a', 2: 'b'}
複製程式碼

值不唯一的情況

d = {'a': 1, 'b': 2, 'c': 3, 'd': 1}
# 想要輸出
{1: ['a', 'd'], 2: ['b'], 3: ['c']}

# 第一種方法
result = {}
for k, v in d.items():
    result[v] = result.get(v, [])
    result[v].append(k)
result

# 第二種方法
result = {}
for k, v in d.items():
    result[v] = result.get(v, []) + [k]
result

# 第三種方法
result = {}
for k, v in d.items():
    result.setdefault(v, []).append(k)
result
複製程式碼

這裡說明一下,getsetdefault的區別是,當鍵不存在時,get會返回設定的預設值,而setdefault會將設定好的預設值對應到鍵上,更改原字典,之後再返回鍵的值。所以說get不能像setdefault那麼用的原因是,初始化時不會自動修改原字典,需要通過賦值實現修改。而如果要找的鍵原本就在字典中存在的話,getsetdefault呼叫append都能對原字典進行修改,具體情況讀者可以自己去試。

如果使用collections模組,還有第四種方法

from collections import defaultdict
result = defaultdict(list)
for k, v in d.items():
    result[v].append(k)
dict(result)
複製程式碼

後面多有用這個思路來完成的,就只展示其中一種方法了。

統計頻數

要統計一個列表中各個元素出現的次數,最後用字典的形式呈現,可以使用collections模組中的defaultdict

from collections import defaultdict
m = ['a', 'b', 'a', 'b', 'a', 'c']
d = defaultdict(lambda: 0)
for k in m:
    d[k] += 1
dict(d)
# {'a': 3, 'b': 2, 'c': 1}
複製程式碼

其實collections模組還提供了一個專門的計數器Counter

from collections import Counter
m = ['a', 'b', 'a', 'b', 'a', 'c']
c = Counter()
for k in m:
    c[k] += 1
dict(c)
# {'a': 3, 'b': 2, 'c': 1}
複製程式碼

從字典中提取資訊

我們現在有這個字典

m = {'Bob': {'age': 30, 'country': 'America'},
     'Mary': {'age': 20, 'country': 'China'},
     'Frank': {'age': 25, 'country': 'America'}}
複製程式碼

1.提取出

{'America': ['Frank', 'Bob'], 'China': ['Mary']}
複製程式碼

程式碼:

result = {}
for k, v in m.items():
    result.setdefault(v['country'], []).append(k)
result
複製程式碼

2.提取出

{'America': [25, 30], 'China': [20]}
複製程式碼

程式碼

result = {}
for k, v in m.items():
    result.setdefault(v['country'], []).append(v['age'])
result
複製程式碼

鍵值轉換

還是這個字典

m = {'Bob': {'age': 30, 'country': 'America'},
     'Mary': {'age': 20, 'country': 'China'},
     'Frank': {'age': 25, 'country': 'America'}}
複製程式碼

現在想要得到下面這種形式(即將鍵移入字典變成一個值)

[{'name': 'Bob', 'age': 30, 'country': 'America'},
 {'name': 'Mary', 'age': 20, 'country': 'China'},
 {'name': 'Frank', 'age': 25, 'country': 'America'}]
複製程式碼

只需要

[{**{'name': name}, **infos} for name, infos in m.items()]
複製程式碼

注:使用雙星號是合併兩個字典的好方法,注意和 將字典列表合併為一個字典相區分

反過來的過程:

m = [{'name': 'Bob', 'age': 30, 'country': 'America'},
     {'name': 'Mary', 'age': 20, 'country': 'China'},
     {'name': 'Frank', 'age': 25, 'country': 'America'}]
     
from collections import defaultdict
result = defaultdict(dict)
for d in m:
    for k, v in d.items():
        if k != 'name':
            result[d['name']].update({k: v})
            
dict(result)
複製程式碼

歡迎關注我的知乎專欄

專欄主頁:python程式設計

專欄目錄:目錄

版本說明:軟體及包版本說明

相關文章