迭代两个不同长度的列表

13

我有两个数字列表,它们的长度可能不同,例如:

list1 = [1, 2, -3, 4, 7]
list2 = [4, -6, 3, -1]

我需要使用这个函数迭代它们:

final_list = []
for index in range(???):
    if list1[index] < 0:
        final_list.insert(0, list1[index])
    elif list1[index] > 0:
        final_list.insert(len(final_list), list1[index])
    if list2[index] < 0:
        final_list.insert(0, list2[index])
    elif list2[index] > 0:
        final_list.insert(len(final_list), list2[index])
return final_list

但是我无法解决如何处理范围的问题,因为如果我使用max长度,较短的列表将变为“超出范围”。你有什么想法克服这个问题或者如何改变我的函数吗?


你想要实现什么目标? - fbence
你能解释一下输出应该是什么吗? - Daniel Roseman
10
for item1, item2 in itertools.zip_longest(list1, list2) - Chris_Rands
使用 itertools 中的 zip_longest - kuro
请解释一下你的逻辑? - zaidfazil
3个回答

18

itertools.zip_longest(*iterables, fillvalue=None)可以帮助你实现此操作:

如果传入的可迭代对象长度不一,则使用指定的fillvalue值填充缺失的值。

对于你的示例列表,这将产生以下结果:

>>> import itertools
>>> list1 = [1, 2, -3, 4, 7]
>>> list2 = [4, -6, 3, -1]

>>> for combination in itertools.zip_longest(list1, list2):
    print(combination)

(1, 4)
(2, -6)
(-3, 3)
(4, -1)
(7, None)
如果您只想使用两个列表中都存在的值,请使用内置的 zip() 函数:

当最短的可迭代对象用尽时,迭代器将停止。

>>> for combination in zip(list1, list2):
    print(combination)

(1, 4)
(2, -6)
(-3, 3)
(4, -1)

2
您可以使用itertools.zip_longest()(如果使用Python 2,则使用itertools.izip_longest())来处理列表中相邻的项目,以生成一系列成对的项目。对于长度不匹配的列表,将使用None填充成对。

然后,您可以通过展开成对项目的序列并过滤掉None值(在您的情况下是0值)来简化循环体中的代码。以下是生成器表达式所做的事情。

然后,只需要将大于零或小于零的值附加或插入到final_list中即可。

在代码中:

from itertools import zip_longest

final_list = []
for value in (i for pair in zip_longest(list1, list2) for i in pair if i):
    if value > 0:
        final_list.append(value)
    else:
        final_list.insert(0, value)

print(final_list)
[-1, -3, -6, 1, 4, 2, 3, 4, 7]
请注意,这将过滤掉可能存在于列表中的任何零值。如果您想保留这些值,则需要修改生成器表达式以仅过滤None值:
(i for pair in zip_longest(list1, list2)
    for i in pair if i is not None)

修改循环体,将0插入到final_list中应该出现的位置。


1
在您的情况下,您可能只需要检查索引是否比序列长度长:
list1 = [1, 2, -3, 4, 7]
list2 = [4, -6, 3, -1]

final_list = []
for index in range(max(len(list1), len(list2))):
    if index < len(list1):
        if list1[index] < 0:
            final_list.insert(0, list1[index])
        elif list1[index] > 0:
            final_list.insert(len(final_list), list1[index])

    if index < len(list2):
        if list2[index] < 0:
            final_list.insert(0, list2[index])
        elif list2[index] > 0:
            final_list.insert(len(final_list), list2[index])

print(final_list)
# [-1, -3, -6, 1, 4, 2, 3, 4, 7]

或者使用 itertools.zip_longest(在 Python 2.x 中为 itertools.izip_longest),并检查一些填充值(即 None)。
import itertools

list1 = [1, 2, -3, 4, 7]
list2 = [4, -6, 3, -1]

final_list = []
for item1, item2 in itertools.zip_longest(list1, list2, fillvalue=None):
    if item1 is None:
        pass
    elif item1 < 0:
        final_list.insert(0, item1)
    elif item1 > 0:
        final_list.append(item1)

    if item2 is None:
        pass
    elif item2 < 0:
        final_list.insert(0, item2)
    elif item2 > 0:
        final_list.append(item2)

然而,你的方法在项目等于0时会跳过,这可能是一个疏忽,但你应该检查它是否正确地处理了零。
另外,你经常使用插入。最后的elif可以改用final_list.append(item1)(或item2),就像我在第二个例子中所做的那样。
在这种情况下,对于item1和item2的处理是相同的,因此你可以使用另一个循环。
import itertools

list1 = [1, 2, -3, 4, 7]
list2 = [4, -6, 3, -1]

final_list = []
for items in itertools.zip_longest(list1, list2, fillvalue=None):
    for item in items:
        if item is None:
            pass
        elif item < 0:
            final_list.insert(0, item)
        elif item > 0:
            final_list.append(item)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接