Есть ли способ иметь параллель для каждого цикла?

Скажем, у меня есть 2 списка в Python, и я хочу прокручивать каждый из них параллельно - например. сделать что-то с элементом 1 для обоих списков, сделать что-то с элементом 2 для обоих списков... Я знаю, что могу это сделать, используя индекс:

for listIndex in range(len(list1)):
   doSomething(list1[listIndex])
   doSomething(list2[listIndex])

Но есть ли способ сделать это более интуитивно, с циклом foreach? Что-то вроде for list1Value in list1, list2Value in list2...?

В настоящее время я сталкиваюсь с этой ситуацией на Python, но это давний вопрос, и мне было бы интересно узнать, можете ли вы сделать это на любом языке. (Я просто предположил, что у Python, скорее всего, есть метод борьбы с этим.)

Ответ 1

Что-то вроде этого?

for (a,b) in zip(list1, list2):
  doSomething(a)
  doSomething(b)

Хотя если doSomething() не выполняет ввод/вывод или обновление глобального состояния, а работает только на одном из элементов за раз, порядок не имеет значения, поэтому вы можете просто использовать chain() (из itertools ):

for x in chain(list1, list2):
  doSomething(x)

Кстати, from itertools import * - это то, что я делаю очень часто. Рассмотрим izip() вместо использования zip(), приведенного выше. Также просмотрите izip_longest(), izip(count(), lst) и т.д. Добро пожаловать в функциональное программирование.: -)

О, и zipping также работает с большим количеством "столбцов":

for idx, a, b, c in izip(count(), A, B, C):
  ...

Ответ 2

Это будет зависеть от языка. На самом деле у Python есть довольно простой способ:

a = (0,1,2,3,4,5,6,7,8,9)
b = "ABCDEFGHIJ"
for pair in zip(a,b):
  print("%d => %s" % pair)

Ответ 3

Используйте zip или itertools.izip для этого:

for item1, item2 in zip(iterable1, iterable2):
    # process the items in parallel

itertools.izip в Python < 3 и zip в Python ≥ 3 возвращают итераторы; то есть они предоставляют кортежи пар (или триплетов, квартетов и т.д.) по запросу. Python < 3 zip создает список кортежей, поэтому требования к памяти могут быть большими, если наименьшая из последовательностей достаточно длинная.