我需要编写一个函数zipper(l1,l2,l3),它接受三个任意长度的列表,包含任意类型的元素。
该函数返回一个列表,其中包含以下列方式排序的这三个列表中的所有元素:列表1的元素1,列表2的元素1,列表3的元素1,列表1的元素2,列表2的元素2等等。当元素用完时,列表停止对最终列表做出贡献。
我尝试过使用此代码:
def zipper(l1,l2,l3):
results = []
length_1 = len(l1) - 1
length_2 = len(l2) - 1
length_3 = len(l3) - 1
g = True
h = True
t = True
i = 0
while(g and h and t):
if(length_1 <= i and g):
results.append(l1[i])
if(length_2 <= i and h):
results.append(l2[i])
if(length_3 <= i and t):
results.append(l3[i])
if(i > length_1):
g = False
elif(i > length_2):
h = False
elif(i > length_3):
t = False
i += 1
return results
l1 = [1, 2, 3, 4, 5, 6, 7]
l2 = ["a", "b", "c"]
l3 = [[1,2], [1,2,3], "test", 300]
print(zipper(l1, l2, l3))
在示例中,结果应为:
[1, 'a', [1, 2], 2, 'b', [1, 2, 3], 3, 'c', 'test', 4, 300, 5, 6, 7]
答案 0 :(得分:3)
这是一种类似于使用zip_longest
和filter
的方法,除了它是手动完成的。当然,在实际代码中,最好使用标准库函数,但是自己实现这些功能可能是一个有趣的学习练习。
此代码将采用任意数量的列表或其他迭代。它从每个迭代创建一个无限的生成器。当iterable耗尽元素时,无限生成器会产生一个名为Done
的标记对象。
我们只是循环遍历这些生成器的列表,将非Done
元素添加到我们的最终result
列表中,当所有生成器生成Done
时停止。
class Done:
pass
def forever(it):
for i in iter(it):
yield i
while True:
yield Done
def zipper(*iterables):
gens = [forever(it) for it in iterables]
result = []
while True:
a = [u for u in [next(g) for g in gens] if u is not Done]
if a == []:
break
result.extend(a)
return result
l1 = [1, 2, 3, 4, 5, 6, 7]
l2 = ["a", "b", "c"]
l3 = [[1,2], [1,2,3], "test", 300]
print(zipper(l1, l2, l3))
<强>输出强>
[1, 'a', [1, 2], 2, 'b', [1, 2, 3], 3, 'c', 'test', 4, 300, 5, 6, 7]
答案 1 :(得分:1)
使用.pop
列表可以大大简化。
这将循环,而任何列表中仍有元素,如果列表仍有项目,它将弹出输入的第一个元素并将其附加到结果列表。
def zipper(l1, l2, l3):
results = []
while l1 or l2 or l3:
if l1:
results.append(l1.pop(0))
if l2:
results.append(l2.pop(0))
if l3:
results.append(l3.pop(0))
return results
答案 2 :(得分:0)
您可以使用itertools.izip_longest
:for python 2x
>>> import itertools
>>> filter(lambda x: x!=None, [y for x in itertools.izip_longest(l1,l2,l3) for y in x])
[1, 'a', [1, 2], 2, 'b', [1, 2, 3], 3, 'c', 'test', 4, 300, 5, 6, 7]
使用itertools.zip_longest
:for python 3x
>>> list(filter(lambda x: x!=None, [y for x in itertools.zip_longest(l1,l2,l3) for y in x]))
[1, 'a', [1, 2], 2, 'b', [1, 2, 3], 3, 'c', 'test', 4, 300, 5, 6, 7]
答案 3 :(得分:0)
from itertools import izip_longest,chain
l1 = [1, 2, 3, 4, 5, 6, 7]
l2 = ["a", "b", "c"]
l3 = [[1,2], [1,2,3], "test", 300]
a =list(chain(*(filter(None, pair) for pair in izip_longest(l1,l2,l3))))
print(a)
答案 4 :(得分:0)
如果我理解正确的话,我会对您的代码进行一些编辑,它可以完成您想要的操作。
def zipper(l1,l2,l3):
results = []
g, h, t = True, True, True
i = 0
while(g or h or t):
if(len(l1) > i):
results.append(l1[i])
else:
g=False
if(len(l2) > i):
results.append(l2[i])
else:
h=False
if(len(l3) > i):
results.append(l3[i])
else:
t=False
i += 1
return results
l1 = [1, 2, 3, 4, 5, 6, 7]
l2 = ["a", "b", "c"]
l3 = [[1,2], [1,2,3], "test", 300]
print(zipper(l1, l2, l3))
输出
[1, 'a', [1, 2], 2, 'b', [1, 2, 3], 3, 'c', 'test', 4, 300, 5, 6, 7]