2014-12-20 28 views
5

迭代的兼容的方式,我有以下列表理解,僅由於使用的iteritems()工作在Python 2:Python 2和3通過與字典鍵和值

foo = [key for key, value in some_dict.iteritems() if value['marked']] 

我無法導入任何庫。有沒有一種乾淨的方式使Python 2和Python 3兼容?

回答

7

你可以簡單地在兩個Python 2和3使用dict.items()

foo = [key for key, value in some_dict.items() if value['marked']] 

或者你可以簡單地推出自己的版本items發生器,這樣

def get_items(dict_object): 
    for key in dict_object: 
     yield key, dict_object[key] 

,然後用它像這樣

for key, value in get_items({1: 2, 3: 4}): 
    print key, value 
5

最簡單的方法是不關心名單是

foo = [key for key, value in some_dict.items() if value['marked']] 

下一個選項是使用異常處理程序:

try: 
    # Python 2 
    iter_some_dict = some_dict.iteritems 
except AttributeError: 
    # Python 3 
    iter_some_dict = some_dict.items 

foo = [key for key, value in iter_some_dict if value['marked']] 

你用什麼取決於some_dict有多大得到,如果列表中的所有項目的創造是通過只使用dict.items()創建會對性能和內存使用產生相當大的影響。您必須對您的確切用例進行基準測試以確定這一點。

2

定義自己的iteritems

iteritems = lambda d: (getattr(d, 'iteritems') or d.items)() 

foo = [key for key, value in iteritems(some_dict) if value['marked']] 
6

我想說的是更好地使用future模塊比實現自己的,很多東西你在簡約/優化的方式已經完成:

from future.utils import viewitems 

foo = [key for key, value in viewitems(some_dict) if value.get('marked')] 

如果你很好奇viewitems()是如何工作的,那麼它很簡單,如下所示:

def viewitems(obj, **kwargs): 
    """ 
    Function for iterating over dictionary items with the same set-like 
    behaviour on Py2.7 as on Py3. 

    Passes kwargs to method.""" 
    func = getattr(obj, "viewitems", None) 
    if not func: 
     func = obj.items 
    return func(**kwargs) 

NB: 如果與Python版本的兼容性2.7之前 需要,那麼你應該使用iteritems()

from future.utils import iteritems 

foo = [key for key, value in iteritems(some_dict) if value.get('marked')]