Python 2和3兼容的方式迭代通过dict与键和值

时间:2014-12-20 14:03:27

标签: python python-3.x dictionary python-2.x

我有以下列表理解,由于使用iteritems()而仅适用于Python 2:

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

我无法导入任何库。有没有一种干净的方法可以兼容Python 2和3?

4 个答案:

答案 0 :(得分:11)

您只需在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

答案 1 :(得分:8)

我认为使用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: 如果与2.7之前的Python版本兼容     然后你应该使用iteritems()

from future.utils import iteritems

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

答案 2 :(得分:6)

最简单的方法是不关心仅使用dict.items()创建的列表:

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获得的大小,以及所有项目列表的创建是否会对性能和内存使用产生相当大的影响。您必须对确切的用例进行基准测试以确定这一点。

答案 3 :(得分:2)

定义您自己的iteritems

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

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