2014-12-20 27 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')]