【问题标题】:python: iterate through two objects in a list at oncepython:一次遍历列表中的两个对象
【发布时间】:2013-07-21 19:44:40
【问题描述】:

通过 python 调用 SQL db,返回列表中成对字典的输出:

[{'Something1A':Num1A}, {'Something1B':Num1B}, {'Something2A':Num2A} ...]

我想遍历这个列表,但同时拉出两个字典。

我知道for obj1, obj2 in <list> 不是正确的方法,但是什么是正确的?

【问题讨论】:

    标签: python list dictionary iteration


    【解决方案1】:

    您可以在列表上使用带有迭代器的 zip 来做到这一点:

    >>> dicts = [{'1A': 1}, {'1B': 2}, {'2A': 3}, {'2B': 4}]
    >>> for obj1, obj2 in zip(*[iter(dicts)]*2):
        print obj1, obj2
    
    
    {'1A': 1} {'1B': 2}
    {'2A': 3} {'2B': 4}
    

    【讨论】:

      【解决方案2】:

      在此处使用zip()

      >>> testList = [{'2': 2}, {'3':3}, {'4':4}, {'5':5}]
      >>> for i, j in zip(testList[::2], testList[1::2]):
              print i, j
      
      
      {'2': 2} {'3': 3}
      {'4': 4} {'5': 5}
      

      替代(不使用zip()):

      for elem in range(0, len(testList), 2):
          firstDict, secondDict = testList[i], testList[i+1]
      

      【讨论】:

      • 列表切片生成一个全新的列表。这将占用额外的空间。更好地使用索引。检查我的代码。
      • 你的代码打印({'2': 2}, {'3': 3})\n({'3': 3}, {'4': 4}),你需要把它改成for i in range(0, len(testList), 2): print(testList[i],testList[i+1])
      • 哎呀!我想是时候打个盹了! :D 你可能想取消你的反对票。
      • 男人!这些家伙甚至不离开 cmets 为什么他们投了反对票!无论如何@Sukrit 感谢您指出我的错误。
      • 建议:也许链接到 Python 3 文档以获取 zip? docs.python.org/3/library/functions.html#zip 一个有经验的 pythonista 可能会马上意识到他们正在查看 python 2 文档,但我是一个 n00b 而我没有。如果您检查此内容,请提前致谢!
      【解决方案3】:
      >>> L = [{'1A': 1},{'1B': 1},{'2A': 2}, {'2B': 2}]
      >>> zip(*[iter(L)]*2)
      [({'1A': 1}, {'1B': 1}), ({'2A': 2}, {'2B': 2})]
      

      【讨论】:

        【解决方案4】:

        我相信在可迭代对象中分组项的 Python 习语是

        zip(*[iter(iterable)])*n)
        

        iterable 是您的字典列表,如果您希望它们以 2 个为一组,n 是 2。

        然后解决方案将如下所示。

        >>> data = [{'A':1}, {'B':2}, {'C':3}, {'D':4}]
        >>> for dict1, dict2, in zip(*[iter(data)]*2):
            print dict1, dict2
        
        
        {'A': 1} {'B': 2}
        {'C': 3} {'D': 4}
        >>> 
        

        这不依赖于切片,这意味着它的内存效率更高并且可能更快,因为在这种情况下 zip 正在“压缩”的两个序列是通过 iter(data) 动态生成的,这意味着 一次通过 而不是 三遍(第一个切片 1 个,第二个切片 1 个,zip 1 个)。

        如果由于某种原因您的数据非常大,那么您可能不想构建一个全新的元组列表,该列表 zip 返回只是为了循环一次。在这种情况下,您可以使用itertools.izip 代替zip

        【讨论】:

          【解决方案5】:

          http://docs.python.org/2/library/itertools.html

          寻找“grouper”,你会使用 n=2。

          import itertools
          def grouper(iterable, n, fillvalue=None):
              "Collect data into fixed-length chunks or blocks"
              # grouper('ABCDEFG', 3, 'x') --> ABC DEF Gxx
              args = [iter(iterable)] * n
              return itertools.izip_longest(fillvalue=fillvalue, *args)
          

          【讨论】:

          • 我很确定他想要的是 (1A, 1B), (2A, 2B) 等等,而不是 (1A, 1B), (1B, 2A) 等等。
          • 啊,是的。谢谢。固定。
          【解决方案6】:

          简单

          在 Python 2 中

          li = [{'Something1A':10}, {'Something1B':201}, {'Something2A':405} ]
          from itertools import imap
          for a,b in imap(lambda x: x.items()[0], li):
              print a,b
          

          在 Python 3 中,map() 已经是一个生成器

          【讨论】:

            【解决方案7】:

            使用索引从列表中获取两个元素。

            testList = [{'2': 2}, {'3':3}, {'4':4}, {'5':5}]
            for i in range(0,len(testList),2):
                print(testList[i],testList[i+1])
            

            【讨论】:

              猜你喜欢
              • 2015-05-25
              • 1970-01-01
              • 2017-04-12
              • 1970-01-01
              • 2021-11-21
              • 2018-11-26
              • 1970-01-01
              • 2016-12-29
              • 1970-01-01
              相关资源
              最近更新 更多