【问题标题】:Is there a better way to iterate over two lists, getting one element from each list for each iteration? [duplicate]有没有更好的方法来迭代两个列表,每次迭代从每个列表中获取一个元素? [复制]
【发布时间】:2010-12-27 12:05:32
【问题描述】:

我有一个纬度列表和一个经度列表,需要遍历纬度和经度对。

是不是更好:

  • A.假设列表长度相等:

    for i in range(len(Latitudes)):
        Lat,Long=(Latitudes[i],Longitudes[i])
    
  • B.或者:

    for Lat,Long in [(x,y) for x in Latitudes for y in Longitudes]:
    

(注意 B 不正确。这给了我所有的对,相当于itertools.product()

对于每一个的相对优点有什么想法,或者哪个更pythonic?

【问题讨论】:

    标签: python list iteration


    【解决方案1】:

    这是你可以得到的最pythonic:

    for lat, long in zip(Latitudes, Longitudes):
        print(lat, long)
    

    【讨论】:

    • 在 Python 2.x 中,您可以考虑使用 itertools.izip(zip 在 Python 3.x 中做同样的事情)。
    • @NicholasRiley:想提一下为什么?
    • 它使用更少的内存并且可能更快;它创建一个迭代器而不是一个中间列表。
    • 如果我还想要索引i怎么办?我可以在枚举中包装那个 zip 吗?
    • for index, (lat,long) in enumerate(zip(Latitudes, Longitudes)):
    【解决方案2】:

    另一种方法是使用map

    >>> a
    [1, 2, 3]
    >>> b
    [4, 5, 6]
    >>> for i,j in map(None,a,b):
        ...   print i,j
        ...
    1 4
    2 5
    3 6
    

    与 zip 相比,使用 map 的一个区别是,使用 zip 新列表的长度是
    与最短列表的长度相同。 例如:

    >>> a
    [1, 2, 3, 9]
    >>> b
    [4, 5, 6]
    >>> for i,j in zip(a,b):
        ...   print i,j
        ...
    1 4
    2 5
    3 6
    

    在同一数据上使用地图:

    >>> for i,j in map(None,a,b):
        ...   print i,j
        ...
    
        1 4
        2 5
        3 6
        9 None
    

    【讨论】:

    • 是否可以这样做:14,15,16??
    • 地图解决方案在 python 3.6 中不起作用。我不得不使用 itertools.zip_longest(a,b) 来达到同样的效果。
    【解决方案3】:

    很高兴在此处的答案中看到对zip 的喜爱。

    但是需要注意的是,如果你使用的是 3.0 之前的 Python 版本,标准库中的 itertools 模块包含一个返回可迭代的 izip 函数,这在这种情况下更合适(特别是如果你的latt/longs 列表很长)。

    在 python 3 及更高版本中,zip 的行为类似于 izip

    【讨论】:

      【解决方案4】:

      如果您的纬度和经度列表很大并且延迟加载:

      from itertools import izip
      for lat, lon in izip(latitudes, longitudes):
          process(lat, lon)
      

      或者如果你想避免for循环

      from itertools import izip, imap
      out = imap(process, izip(latitudes, longitudes))
      

      【讨论】:

        【解决方案5】:
        for Lat,Long in zip(Latitudes, Longitudes):
        

        【讨论】:

          【解决方案6】:

          同时遍历两个列表的元素称为压缩,python 为它提供了一个内置函数,记录在 here

          >>> x = [1, 2, 3]
          >>> y = [4, 5, 6]
          >>> zipped = zip(x, y)
          >>> zipped
          [(1, 4), (2, 5), (3, 6)]
          >>> x2, y2 = zip(*zipped)
          >>> x == list(x2) and y == list(y2)
          True
          

          [示例取自 pydocs]

          在你的情况下,它只是:

          for (lat, lon) in zip(latitudes, longitudes):
              ... process lat and lon
          

          【讨论】:

            【解决方案7】:

            这篇文章帮助了我zip()。我知道我迟到了几年,但我仍然想做出贡献。这是在 Python 3 中。

            注意:在 python 2.x 中,zip() 返回一个元组列表;在 Python 3.x 中,zip() 返回一个迭代器。 itertools.izip() 在 python 2.x == zip() 在 python 3.x

            由于您正在构建一个元组列表,因此以下代码是尝试完成您正在做的事情的最 Pythonic 方式。

            >>> lat = [1, 2, 3]
            >>> long = [4, 5, 6]
            >>> tuple_list = list(zip(lat, long))
            >>> tuple_list
            [(1, 4), (2, 5), (3, 6)]
            

            或者,如果您需要更复杂的操作,您可以使用list comprehensions(或list comps)。列表推导的运行速度也与 map() 一样快,大约需要几纳秒,并且正在成为 Pythonic 与 map() 的新规范。

            >>> lat = [1, 2, 3]
            >>> long = [4, 5, 6]
            >>> tuple_list = [(x,y) for x,y in zip(lat, long)]
            >>> tuple_list
            [(1, 4), (2, 5), (3, 6)]
            >>> added_tuples = [x+y for x,y in zip(lat, long)]
            >>> added_tuples
            [5, 7, 9]
            

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 2015-12-25
              • 2014-03-12
              • 2015-01-17
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多