Как в Python перебирать кортежи элементов двух или более списков?

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

a = ['foo1', 'foo2', 'foo3']
b = ['bar1', 'bar2', 'bar3']

Мне нужна функция comb_to_lines (), которая возвращала бы:

"""foo1 bar1
foo2 bar2
foo3 bar3"""

Признаюсь, я уже решил эту проблему, поэтому опубликую ответ. Но, возможно, у кого-то есть лучший или кто-то видит недостаток в моем.

Обновление: я слишком упростил приведенный выше пример. В моей реальной проблеме строки были отформатированы более сложным образом, что потребовало распаковки кортежей, возвращаемых из zip (). Но спасибо mhawke за то, что он нашел простейшее решение для этого примера.


person Daryl Spitzer    schedule 31.07.2009    source источник


Ответы (7)


Нет необходимости распаковывать и переупаковывать кортежи, возвращаемые zip:

'\n'.join(' '.join(x) for x in zip(a, b))
person mhawke    schedule 31.07.2009

zip function "возвращает список кортежей, где i-й кортеж содержит i-й элемент из каждой из последовательностей аргументов или итераций. "

def combine_to_lines(list1, list2):
    return '\n'.join([' '.join((a, b)) for a, b in zip(list1, list2)])
person Daryl Spitzer    schedule 31.07.2009

Вы спрашиваете о функции zip?

person S.Lott    schedule 31.07.2009
comment
да. Я не мог этого вспомнить, и поиск в Google занял немного времени, чтобы разбудить мою память. Возможно, этот вопрос возникнет в будущих поисках. - person Daryl Spitzer; 31.07.2009
comment
это действительно так, и это помогло мне пробудить мою память. так что спасибо тебе. - person aeroNotAuto; 27.07.2012
comment
Другой вопрос как ответ на вопрос? :) - person Sнаđошƒаӽ; 16.02.2016

Я понимаю, что это очень старый вопрос, но интересно отметить, что его можно рассматривать как транспонирование матрицы.

>>> import numpy
>>> data = numpy.array([['foo1','foo2','foo3'],['bar1','bar2','bar3']])
>>> print(data)
[['foo1' 'foo2' 'foo3']
 ['bar1' 'bar2' 'bar3']]
>>> print(data.transpose())
[['foo1' 'bar1']
 ['foo2' 'bar2']
 ['foo3' 'bar3']]

Если вы имеете дело с большим набором данных или несколькими списками, это может быть более эффективным решением.

person xthrd    schedule 16.12.2013

Вот однострочный. Мог бы сделать x + ' ' + y, если бы вы были так склонны, не уверены, будет ли это медленнее или нет.

>>> a = ['foo1', 'foo2' , 'foo3']
>>> b = ['bar1', 'bar2', 'bar3']
>>> '\n'.join(' '.join([x,y]) for (x,y) in zip(a,b))
'foo1 bar1\nfoo2 bar2\nfoo3 bar3'
>>> print _
foo1 bar1
foo2 bar2
foo3 bar3
person Mark Rushakoff    schedule 31.07.2009

Просто как:

" ".join([a[x] + " " + b[x] for x in range(len(a))])
person Denis Masyukov    schedule 31.07.2009
comment
где новые строчки? - person mhawke; 31.07.2009

В python 3.x:

'\n'.join(' '.join(x) for x in zip(a, b))

zip возвращает список кортежей. zip останавливается, когда останавливается более короткий из a или b.

В python 2.x:

если itertools.izip остановится, когда в одном из списков закончатся элементы, но itertools.izip_longest остановится, пока в списках не останется элементов

import itertools
'\n'.join(' '.join(x) for x in itertools.izip(a, b))

'\n'.join(' '.join(x) for x in itertools.izip_longest(a, b))
person Mehrdad Mehraban    schedule 18.07.2014
comment
Также благодарю mhawke за то, что он придумал основное решение - person Mehrdad Mehraban; 18.07.2014
comment
Почему вы пишете на Python 3.x выше? Я только что подтвердил, что zip останавливается, когда останавливается более короткий из a или b на Python 2.7.5. - person Daryl Spitzer; 29.07.2014
comment
ты прав! насколько я понимаю, раньше этой функции не было в python 2.x, и она была перенесена из 3.x, я прав? если да, то с какой версии я был обновлен? - person Mehrdad Mehraban; 30.07.2014