У меня есть два списка
a = [1,2,3]
b = [9,10]
Я хочу объединить (zip) эти два списка в один список c
, чтобы
c = [(1,9), (2,10), (3, )]
Есть ли какая-либо функция в стандартной библиотеке в Python для этого?
У меня есть два списка
a = [1,2,3]
b = [9,10]
Я хочу объединить (zip) эти два списка в один список c
, чтобы
c = [(1,9), (2,10), (3, )]
Есть ли какая-либо функция в стандартной библиотеке в Python для этого?
То, что вы ищете, itertools.izip_longest
>>> a = [1,2,3]
>>> b = [9,10]
>>> for i in itertools.izip_longest(a,b): print i
...
(1, 9)
(2, 10)
(3, None)
EDIT 1. Если вы действительно хотите избавиться от None
s, вы можете попробовать:
>>> for i in (filter(None, pair) for pair in itertools.izip_longest(a,b)): print i
(1, 9)
(2, 10)
(3,)
РЕДАКТИРОВАТЬ 2: В ответ на комментарий steveha:
filter(lambda p: p is not None, pair) for pair in itertools.izip_longest(a,b)
Другой способ: map
:
a = [1, 2, 3]
b = [9, 10]
c = map(None, a, b)
Хотя это тоже будет содержать (3, None)
вместо (3,)
. Чтобы сделать это, вот забавная строка:
c = (tuple(y for y in x if y is not None) for x in map(None, a, b))
Не слишком сложно просто написать явный Python для выполнения нужной операции:
def izip_short(a, b):
ia = iter(a)
ib = iter(b)
for x in ia:
try:
y = next(ib)
yield (x, y)
except StopIteration:
yield (x,)
break
for x in ia:
yield (x,)
for y in ib:
yield (None, y)
a = [1, 2, 3]
b = [9, 10]
list(izip_short(a, b))
list(izip_short(b, a))
Я не был уверен, как вы хотите обрабатывать последовательность b
длиннее последовательности a
, поэтому я просто использую None
для первого значения в кортеже в этом случае.
Получить явный итератор для каждой последовательности. Запустите тег a
как цикл for
, используя вручную next(ib)
, чтобы получить следующее значение из последовательности b
. Если мы получим a StopIteration
в последовательности b
, мы разбиваем цикл, а затем for x in ia:
получает остальную часть последовательности a
; после этого for y in ib:
ничего не сделает, потому что итератор уже исчерпан. В качестве альтернативы, если первый цикл for x in ia:
исчерпывает итератор a
, второй for x in ia:
ничего не делает, но в последовательности b
могут быть оставлены значения, и цикл for y in ib:
их собирает.
Одиночная строка:
c = zip(a, b) + [(x,) for x in a[len(b):]] + [(x,) for x in b[len(a):]]
Если вы хотите повторно использовать это:
def mergeUsNicely(a, b):
def tupleMe(val):
return (val,)
return zip(a, b) + map(tupleMe, a[len(b):]) + map(tupleMe, b[len(a):])