Python 如何";zip";不同大小的列表?

Python 如何";zip";不同大小的列表?,python,python-3.x,list,Python,Python 3.x,List,zip()仅适用于相同大小的列表 a = [2, 4, 6] b = [1, 2, 3] zip(a, b) 输出: [(2, 1), (4, 2), (6, 3)] [(1, 2), (3, 4), (5, 6), (7, 8), (9), (11)] 我想以某种方式zip不同大小的列表,这样在遍历所有列表时,即使其中一个列表用完,我仍然可以比较其余的列表 例: 输出: [(2, 1), (4, 2), (6, 3)] [(1, 2), (3, 4), (5, 6), (7, 8),

zip()
仅适用于相同大小的列表

a = [2, 4, 6]
b = [1, 2, 3]
zip(a, b)
输出:

[(2, 1), (4, 2), (6, 3)]
[(1, 2), (3, 4), (5, 6), (7, 8), (9), (11)]
我想以某种方式
zip
不同大小的列表,这样在遍历所有列表时,即使其中一个列表用完,我仍然可以比较其余的列表

例:

输出:

[(2, 1), (4, 2), (6, 3)]
[(1, 2), (3, 4), (5, 6), (7, 8), (9), (11)]

是否有一个函数可以执行此操作?或者我必须编写单独的代码才能实现它吗?

这并不漂亮,但这就是我想到的:

In [10]: a = [1, 3, 5, 7, 9, 11]
   ...: b = [2, 4, 6, 8]

In [11]: output = (tuple(l[i] for l in (a,b) if i < len(l)) for i, e in enumerate(max(a,b, key=len)))

In [12]: list(output)
Out[12]: [(1, 2), (3, 4), (5, 6), (7, 8), (9,), (11,)]
[10]中的
a=[1,3,5,7,9,11]
…:b=[2,4,6,8]
[11]中:输出=(如果i

使其成为一种功能:

from collections.abc import (Iterable, Iterator)
from itertools import count

def zip_staggered(*args: Iterable) -> Iterator[tuple]:
    for i in count():
        if (next_elem := tuple(a[i] for a in args if i < len(a))):
            yield next_elem
        else:
            break
from collections.abc导入(Iterable,迭代器)
从itertools导入计数
def zip_交错(*args:Iterable)->迭代器[元组]:
因为我在计数()
if(next_elem:=元组(如果i
这并不漂亮,但我想到的是:

In [10]: a = [1, 3, 5, 7, 9, 11]
   ...: b = [2, 4, 6, 8]

In [11]: output = (tuple(l[i] for l in (a,b) if i < len(l)) for i, e in enumerate(max(a,b, key=len)))

In [12]: list(output)
Out[12]: [(1, 2), (3, 4), (5, 6), (7, 8), (9,), (11,)]
[10]中的
a=[1,3,5,7,9,11]
…:b=[2,4,6,8]
[11]中:输出=(如果i

使其成为一种功能:

from collections.abc import (Iterable, Iterator)
from itertools import count

def zip_staggered(*args: Iterable) -> Iterator[tuple]:
    for i in count():
        if (next_elem := tuple(a[i] for a in args if i < len(a))):
            yield next_elem
        else:
            break
from collections.abc导入(Iterable,迭代器)
从itertools导入计数
def zip_交错(*args:Iterable)->迭代器[元组]:
因为我在计数()
if(next_elem:=元组(如果i
您可以使用,它可以同时处理任意数量的,即使它们包含
None

from itertools import zip_longest

def zipper(*iterables):
    _FILLER = object()  # Value that couldn't be in data.
    for result in (grp for grp in zip_longest(*iterables, fillvalue=_FILLER)):
        yield tuple(v for v in result if v is not _FILLER)


a = [1, None, 3, 5, 7, 9, 11]
b = [2, 4, None, 6, None, 8]

result = list(zipper(a, b))
print(result)  # -> [(1, 2), (None, 4), (3, None), (5, 6), (7, None), (9, 8), (11,)]
更新

以下是它的功能版本:

from itertools import zip_longest
from operator import is_not
from functools import partial

_FILLER = object()  # Value that couldn't be in data.
IS_NOT_FILLER = partial(is_not, _FILLER)

def zipper(*iterables):
    yield from (tuple(filter(IS_NOT_FILLER, group))
                    for group in zip_longest(*iterables, fillvalue=_FILLER))
您可以使用,它可以同时处理任意数量的,即使它们包含
None

from itertools import zip_longest

def zipper(*iterables):
    _FILLER = object()  # Value that couldn't be in data.
    for result in (grp for grp in zip_longest(*iterables, fillvalue=_FILLER)):
        yield tuple(v for v in result if v is not _FILLER)


a = [1, None, 3, 5, 7, 9, 11]
b = [2, 4, None, 6, None, 8]

result = list(zipper(a, b))
print(result)  # -> [(1, 2), (None, 4), (3, None), (5, 6), (7, None), (9, 8), (11,)]
更新

以下是它的功能版本:

from itertools import zip_longest
from operator import is_not
from functools import partial

_FILLER = object()  # Value that couldn't be in data.
IS_NOT_FILLER = partial(is_not, _FILLER)

def zipper(*iterables):
    yield from (tuple(filter(IS_NOT_FILLER, group))
                    for group in zip_longest(*iterables, fillvalue=_FILLER))

使用
intertools.zip_longest()
请记住
(9)
不是一个元组。您可能期望
(9,)
也请记住
(9,)
不会提供有关哪个输入用完的信息。
zip\u longest
的填充行为在这方面更有用。请使用
intertools.zip\u longest()
记住
(9)
不是一个元组。您可能期望
(9,)
也请记住
(9,)
不会提供有关哪个输入用完的信息。在这方面,
zip\u longest
的填充行为更有用。这对我有用,希望对你也有用!a=[1,2,3]b=[4,5,6,7,8]从itertools导入zip_longest c=[]对于压缩后的zip_longest(a,b):non_none=tuple(filter(none,zipped))c.append(non_none)print(c)@NisargBhatt:
filter(none,zipped)
不过滤出非
none
值,它只产生了压缩的
的每个元素。这对我很有效,希望它也对你有效!a=[1,2,3]b=[4,5,6,7,8]从itertools导入zip_longest c=[]对于压缩后的zip_longest(a,b):non_none=tuple(filter(none,zipped))c.append(non_none)print(c)@NisargBhatt:
filter(none,zipped)
不过滤出非
none
值,它只生成压缩的
的每个元素。