Python:如何使用for循环合并两个列表(如zip)

时间:2019-08-03 02:22:08

标签: python list for-loop append

我遇到一个问题,我有一个函数接受两个整数列表,并返回将两个整数列表压缩在一起的单个整数列表(新列表)。

例如:

list1 = [1,2,3]
list2 = [4,5,6]

应该给[1, 4, 2, 5, 3, 6]而不是[1, 2, 3, 4, 5, 6]

另一种情况是,一个列表比另一个列表长,例如:

list1 = [1,2]
list2 = [4,5,6,9]

一旦较短的列表用完了项目,较长的列表应添加其剩余元素。例如:[1, 4, 2, 5, 6, 9]

我尝试使用条件语句来检查哪个列表更长,并使用for循环将其追加到应返回的新列表中。我尝试使用for循环,该循环在较短列表的持续时间内循环,一旦for循环结束,它将把较长列表中的剩余元素添加到新列表中。另外,如果两个列表都是空的,我必须返回一个空的新列表。

代码:

def main():
    list1 = [1,2]
    list2 = [4,5,6,9]
    print(zip_lists(list1, list2))

def zip_lists(list1, list2):
    new_list = []

    if len(list1) > len(list2):
        last_num = list1[len(list1):]
        for num in range(0, len(list2)):
            new_list.append(list1[num])
            new_list.append(list2[num])
        new_list.append(last_num)
        return new_list

    elif len(list2) > len(list1):
        last_num = list2[len(list2):]
        for num in range(0, len(list1)):
            new_list.append(list1[num])
            new_list.append(list2[num])
        new_list.append(last_num)
        return new_list


    elif len(list1) and len(list2) == 0:
        return new_list


main()

但是,我有一个问题,我无法添加较长列表中的其余元素,而是返回带有空方括号的部分压缩列表。

测试案例:

list1 = [1,2]
list2 = [4,5,6,9]

应该是[1、4、2、5、6、9],但我却得到了[1、4、2、5,[]]。

我的代码是否显示了思考此问题的正确方法?

4 个答案:

答案 0 :(得分:1)

def zip_lists(list1, list2):
    n1=len(list1)
    n2=len(list2)
    k = []
    n = min(n1, n2)
    for i in range(n):
        k.append(list1[i])
        k.append(list2[i])

    if n1==n2:
        return k 
    if n1>n2:
        return k+list1[n:]
    else:
        return k+list2[n:]

测试:

list1 = [1,2]
list2 = [4,5,6,9]
zip_lists(list1, list2) 

输出:[1, 4, 2, 5, 6, 9]

答案 1 :(得分:1)

您可以使用zip_longest来做到这一点:

代码:

from itertools import zip_longest
def merge(l1, l2):
    for i in zip_longest(l1, l2):
        for j in i:
            if j is not None:
                yield j

测试代码:

list1 = [1, 2, 3]
list2 = [4, 5, 6]
ans1 = [1, 4, 2, 5, 3, 6]

list3 = [1, 2]
list4 = [4, 5, 6, 9]
ans2 = [1, 4, 2, 5, 6, 9]

assert list(merge(list1, list2)) == ans1
assert list(merge(list3, list4)) == ans2

答案 2 :(得分:1)

Python的itertools standard library文档在"recipes" section中将其命名为roundrobin,显示了其通用版本(即,对于任意数量的源可迭代对象,可能具有不同的长度)。 。已在此处复制,并带有原始信用证:

def roundrobin(*iterables):
    "roundrobin('ABC', 'D', 'EF') --> A D E B F C"
    # Recipe credited to George Sakkis
    num_active = len(iterables)
    nexts = cycle(iter(it).__next__ for it in iterables)
    while num_active:
        try:
            for next in nexts:
                yield next()
        except StopIteration:
            # Remove the iterator we just exhausted from the cycle.
            num_active -= 1
            nexts = cycle(islice(nexts, num_active))

这里,cycleisliceitertoolsfrom itertools import cycle, islice)提供的功能;其余部分是内置的。请注意,这是一个生成器,而不是正常功能。您将需要自己对其进行迭代(或直接从中创建一个列表,例如merged = list(roundrobin(list1, list2)))。


至于调试代码尝试,让我们考虑list1较长的情况(list2较长的情况有并行问题;而相等的情况正在起作用很好,是吗?):

    last_num = list1[len(list1):] # problem 1
    for num in range(0, len(list2)):
        new_list.append(list1[num])
        new_list.append(list2[num])
    new_list.append(last_num) # problem 2

问题1:您要从list1中提取“多余”元素,并将其确定为超过某个点的所有元素。这只是一个错字,或者没有清楚地考虑它。您想使用 list2 的长度作为要分割的元素数量;当然,使用list1的长度从list1中删除元素会删除所有内容。

问题2:您有一个列表,想要将其元素连接到另一个列表的末尾。 .append将其参数视为一个新的列表元素,即使它是一个列表也是如此。就像Python的Zen所说的special cases aren't special enough to break the rules(请记住,有时候您可能想要这样做)。您正在寻找的方法是.extend

答案 3 :(得分:0)

import numpy as np
l=len(a) if len(a)<len(b) else len(b)
a=np.array(list1[:l])
b=np.array(list2[:l])
ab=np.vstack((a, b)).T.flatten()
res=list(ab)+list1[l:]+list2[l:]