天天看點

字典對象的Pythonic用法:上篇

字典對象在Python中作為最常用的資料結構之一,和數字、字元串、清單、元組并列為5大基本資料結構,字典中的元素通過鍵來存取,而非像清單一樣通過偏移存取。筆者總結了字典的一些常用Pyhonic用法,這是字典的Pythonic用法的上篇

判斷某個 key 是否存在于字典中時,一般初學者想到的方法是,先以清單的形式把字典所有鍵傳回,再判斷該key是否存在于鍵清單中:

<code>   dictionary = {}</code>

<code>   keys = dictionary.keys()</code>

<code>   for k in keys:</code>

<code>       if key == k:</code>

<code>           print True</code>

<code>           break</code>

更具Pythonic的用法是使用 <code>in</code>關鍵字來判斷 key 是否 存在于字典中:

<code>   if key in dictionary:</code>

<code>       print True</code>

<code>   else:</code>

<code>       print False</code>

使用字典的時候經常會遇到這樣一種應用場景:動态更新字典,像如下代碼,如果 key 不在 dictionary 中那麼就添加它并把它對應的值初始為空清單 [] ,然後把元素 append 到空清單中:

<code>dictionary = {}</code>

<code>if "key" not in dictionary:</code>

<code>   dictionary["key"] = []</code>

<code>dictionary["key"].append("list_item")</code>

盡管這段代碼沒有任何邏輯錯誤,但是我們可以使用 <code>setdefault</code>來實作更Pyhonic的寫法:

<code>dictionary.setdefault("key", []).append("list_item")</code>

字典調用 setdefault 方法時,首先檢查 key 是否存在,如果存在該方法什麼也不做,如果不存在 setdefault 就會建立該 key,并把第二個參數 <code>[]</code>作為 key 對應的值。

初始化一個字典時,如果初始情況下希望所有 key 對應的值都是某個預設的初始值,比如有一批使用者的信用積分都初始為100,現在想給 <code>a</code> 使用者增加10分

<code>d = {}</code>

<code>if 'a' not in d:</code>

<code>   d['a'] = 100</code>

<code>d['a'] += 10</code>

同樣這段代碼也沒任何問題,換成更pyhtonic的寫法是:

<code>from collections import defaultdict</code>

<code>d = defaultdict(lambda: 100)</code>

defaultdict 是位于 collections 子產品下,它是 <code>dict</code> 類的子類,文法結構是:

<code>class collections.defaultdict([default_factory[, ...]])</code>

第一個參數 <code>default_factory</code>是一個工廠方法,每次初始化某個鍵的時候将會被調用,value就是 <code>default_factory</code>傳回的值,剩下的參數和 <code>dict()</code>函數接收的參數一樣

疊代大資料字典時,如果是使用 items() 方法,那麼在疊代之前,疊代器疊代前需要把資料完整地加載到記憶體,這種方式不僅處理非常慢而且浪費記憶體,下面代碼約占1.6G記憶體(為什麼是1.6G?可以參考:http://stackoverflow.com/questions/4279358/pythons-underlying-hash-data-structure-for-dictionaries)

<code>d = {i: i * 2 for i in xrange(10000000)}</code>

<code>for key, value in d.items():</code>

<code>   print("{0} = {1}".format(key, value))</code>

而使用 iteritem() 方法替換 items() ,最終實作的效果一樣,但是消耗的記憶體降低50%,為什麼差距那麼大呢?因為 items() 傳回的是一個 list,list 在疊代的時候會預先把所有的元素加載到記憶體,而 iteritem() 傳回的一個疊代器(iterators),疊代器在疊代的時候,疊代元素逐個的生成。

<code>for key, value in d.iteritem():</code>

轉自:https://mp.weixin.qq.com/s?__biz=MzI5NDY1MjQzNA==&amp;mid=2247485582&amp;idx=2&amp;sn=701d78855d60af619acbbaeeef40e9e1&amp;chksm=ec5ed7f3db295ee5d2bb69fbecb12818e21330203d259cbdb156adb5aa6a4ed2d4f6033d3674&amp;scene=21#wechat_redirect

繼續閱讀