Есть ли лучший способ перебора двух списков, получая по одному элементу из каждого списка для каждой итерации?

У меня есть список широт и одна из долгот и нужно перебирать пары широты и долготы.

Лучше ли:

  • а. Предположим, что списки имеют одинаковую длину:

    for i in range(len(Latitudes):
        Lat,Long=(Latitudes[i],Longitudes[i])
    
  • В

    . Или:

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

(Обратите внимание, что B неверно. Это дает мне все пары, эквивалентные itertools.product())

Любые мысли об относительных достоинствах каждого, или более пифонические?

Ответ 1

Это как пифонов, как вы можете получить:

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

Ответ 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: с 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

Ответ 3

Приятно видеть много любви к zip в ответах здесь.

Однако следует отметить, что если вы используете версию python до 3.0, модуль itertools в стандартной библиотеке содержит функцию izip, которая возвращает итерабельность, что более подходит в этом случае (особенно если ваш список ребер/длин - довольно длинный).

В python 3 и более поздних zip ведет себя как izip.

Ответ 4

если ваши списки широты и долготы большие и лениво загружены:

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

или если вы хотите избежать цикла for-loop

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

Ответ 5

Итерация через элементы из двух списков одновременно называется zipping, а python предоставляет встроенную функцию для нее, которая документирована здесь.

>>> 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

Ответ 6

for Lat,Long in zip(Latitudes, Longitudes):

Ответ 7

Этот пост помог мне с zip(). Я знаю, что я опаздываю на несколько лет, но я все равно хочу внести свой вклад. Это в Python 3.

Примечание: в python 2.x, zip() возвращает список кортежей; в Python 3.x, zip() возвращает итератор. itertools.izip() в python 2.x == zip() в python 3.x

Поскольку похоже, что вы создаете список кортежей, следующий код является самым питоническим способом выполнить то, что вы делаете.

>>> 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]