我遇到一个问题,我有一个函数接受两个整数列表,并返回将两个整数列表压缩在一起的单个整数列表(新列表)。
例如:
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,[]]。
我的代码是否显示了思考此问题的正确方法?
答案 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))
这里,cycle
和islice
是itertools
(from 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:]