Подтвердить что ты не робот

Закрепление неравных списков в python в список, который не отбрасывает ни один элемент из более длинного списка,

У меня есть два списка

a = [1,2,3]
b = [9,10]

Я хочу объединить (zip) эти два списка в один список c, чтобы

c = [(1,9), (2,10), (3, )]

Есть ли какая-либо функция в стандартной библиотеке в Python для этого?

4b9b3361

Ответ 1

То, что вы ищете, 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)

Ответ 2

Другой способ: 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))

Ответ 3

Не слишком сложно просто написать явный 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: их собирает.

Ответ 4

Одиночная строка:

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