思考一個小細節,從如何反轉字典說起
在某些特定的場景,你會遇到這樣的需求,將字典的 key 和 value 進行互換,例如:
d = { 'a': 1, 'b':2 }
變成
d = { 1: 'a', 2: 'b' }
你可能最先能想到的土辦法就是遍歷字典,逐個將 key-value 互換成 value-key 放進新字典中
d = {'a': 1, 'b': 2}
new_d = dict()
for key in d:
value = d[key]
new_d[value] = key
其實啊,如果你知道推導式概念的話,那麼用一行程式碼就可以搞定。自從 Python2.7和 Python3 加入了列表推導式、集合推導式和字典推導式之後,解決這類問題就得心應手了。用字典推導式可優雅寫出:
new_d = {v: k for k, v in d.items()}
如果你熟悉列表推導式,上面的程式碼你也覺得很眼熟,就是將 key,value 互換構成新的字典。也有人可能會推薦你使用函數語言程式設計風格的程式碼來實現:
>>> d = { 'a': 1, 'b':2 }
>>> dict((map(reversed, d.items())))
{1: 'a', 2: 'b'}
函數語言程式設計風格的程式碼看起來可讀性並沒有那麼好,而且效率上也比不上推導式,我們可以用 timeit 證實一下
>>> import timeit
>>> timeit.timeit("dict((map(reversed, {'a': 1, 'b': 2}.items())))", number=100000)
0.16313515009824187
>>> timeit.timeit("{v: k for k, v in {'a': 1, 'b': 2}.items()}", number=100000)
0.06065327790565789
一看速度上慢將近 3 倍,自從 Python 引入了推導式特性後, map、filter、reduce 這樣的函式就很少被推薦使用了。
在來思考一個問題,為什麼字典自己沒有提供這樣的 API 介面給我們使用?
根據字典的特性:
字典的 key 必須是唯一的,相同的 key 會被覆蓋, 而 value 可以相同,所以這個反轉,就是 key 和 value 都是唯一的場景下。
key 必須是可 hash 的,所以如果 value 是不可 hash 的物件,比如列表,就不能做為 key 了。
因此字典反轉只適合某些特定場景,而不適合當做一個通用操作來使用,所以字典的API裡面也就不會提供這樣的操作了。
推薦閱讀
優秀如你都在關注
相關文章
- 一個小的技術細節
- mybatis快取,從一個“靈異”事件說起MyBatis快取事件
- 從一個跨二十年的glibc bug說起
- 小細節
- 利用遞迴方法實現連結串列反轉、前N個節點反轉以及中間部分節點反轉遞迴
- 從《黑客帝國》說起,我們如何證明這個世界不是一個系統?黑客
- 從一個埋點日誌上報指令碼說起指令碼
- 掌握Rabbitmq幾個重要概念,從一條訊息說起MQ
- 從 JSON 說起JSON
- Node 中如何引入一個模組及其細節
- 從 Gzip 壓縮 SVG 說起 — 論如何減小資原始檔的大小SVG
- 從一個案例,細說瀏覽器的事件迴圈瀏覽器事件
- day01-從一個基礎的socket服務說起
- 後蘋果時代轉型,從裁員說起蘋果
- 定義一個函式,輸入一個連結串列的頭節點,反轉該連結串列並輸出反轉後連結串列的頭節點函式
- Vue、Javascript小細節VueJavaScript
- 說說在 Python 中如何遍歷字典Python
- 從一道面試題說起—js隱式轉換踩坑合集面試題JS
- 從一道筆試題題說起筆試
- 2019情人節一個人QQ簽名 一個人的情人節傷感說說句子
- Laravel 的一個命名細節分享Laravel
- iOS逆向——從RSA說起iOS
- 從SEQUENCE跳號說起
- 從測試說起(二)
- 反轉一個單連結串列。
- 6個敏捷轉型挑戰及其解決方法:從搭建專案管理要素說起敏捷專案管理
- 黑客說:如何做到 4 天上線一個小程式?黑客
- 從 Google 的一道面試題說起·Go面試題
- 從一次Kafka當機說起(JVM hang)KafkaJVM
- 小白細節思考之讀取Request.Body
- 超細!細說Zookeeper選舉的一個案例(下)
- 超細!細說Zookeeper選舉的一個案例(上)
- 從專案的一個 panic 說起:Go 中 Sync 包的分析應用Go
- 從 CALayer 的 Position、AnchorPoint 說起
- 從 RouterModule.forRoot 方法說起
- 將一個字串進行反轉:將字串中指定部分進行反轉。比如“abcdefg”反轉為”abfedcg”字串
- Event Loop是個什麼玩意:從 Vue 的 nextTick 說起OOPVue
- 從一道春招筆試題說起 [上]筆試