【问题标题】:Python 2 and 3 compatible way of iterating through dict with key and valuePython 2 和 3 兼容的方式通过键和值迭代 dict
【发布时间】:2023-04-06 11:58:01
【问题描述】:

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

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

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

【问题讨论】:

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


    【解决方案1】:

    您可以在 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
    

    【讨论】:

      【解决方案2】:

      我想说使用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)
      

      注意: 如果与 2.7 之前的 Python 版本的兼容性是 需要,那么你应该使用iteritems():

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

      【讨论】:

        【解决方案3】:

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

        【讨论】:

          【解决方案4】:

          定义你自己的iteritems:

          iteritems = lambda d: ((hasattr(d, 'iteritems') and d.iteritems) or d.items)()
          
          foo = [key for key, value in iteritems(some_dict) if value['marked']]
          

          【讨论】:

            最近更新 更多