我在Python中混合了两个列表,虽然我知道有类似的问题,但我需要以某种方式处理它。
我有两个列表,它们的长度可能相同,也可能不同。我需要交织两者并使用填充物作为较短的列表,但填充物必须在较短列表中的任何值之前。
这就是我目前所拥有的:
def mix(a, b):
fill='spam'
if len(a) > len(b):
d = len(a) - len(b)
while d:
b.insert(0, fill)
d-=1
if len(a) < len(b):
d = len(b) - len(a)
while d:
a.insert(0, fill)
d-=1
n = zip(a, b)
mixed = [item for sub in n for item in sub]
return mixed
示例:
>>> mix([1, 2 ,3], ['A', 'B', 'C', 'D', 'E', 'F'])
['spam', 'A', 'spam', 'B', 'spam', 'C', 1, 'D', 2, 'E', 3, 'F']
所以代码可以工作,但它似乎不是一个好方法。还有更好的方法吗?
答案 0 :(得分:5)
如果要将一个元素粘贴到列表中的两个元素上,可以利用切片。
这是一个可能的实现:
In [39]: l1 = [1,2,3]
...: l2 = ['A', 'B', 'C', 'D', 'E', 'F']
...: fill = 'spam'
...:
In [40]: l = 2 * max(len(l1), len(l2)) # final length
...: mixed = [fill] * l # result is initialized with the filler
...: mixed[l-2*len(l1)::2] = l1 # paste l1
...: mixed[l-2*len(l2)+1::2] = l2 # paste l2
...: mixed
...:
Out[40]: ['spam', 'A', 'spam', 'B', 'spam', 'C', 1, 'D', 2, 'E', 3, 'F']
答案 1 :(得分:1)
import itertools
def mix(a, b):
diff = len(a) - len(b)
fill = 'spam'
if diff > 0:
b = [fill] * diff + b
elif diff < 0:
a = [fill] * abs(diff) + a
return list(itertools.chain(*zip(a, b)))
您可能听说Python包含电池,即它可能具有内置的实用程序/功能,这有助于使程序更简单,更易读。上述功能与原始功能有两个主要区别:
例如:
>>> [1, 2, 3] + ['a', 'b']
>>> [1, 2, 3, 'a', 'b']
>>> [1] * 3
>>> [1, 1, 1]
>>> [1, 2] * 2
>>> [1, 2, 1, 2]
itertools.chain
function :这个函数只是将作为参数提供给它的迭代器/迭代的列表(不是python列表)链接到单个迭代器中。例如:
>>> list(itertools.chain([1, 2], [3, 4], [5, 6]))
>>> [1, 2, 3, 4, 5, 6]
答案 2 :(得分:0)
不能说这是一种更好的方法,但它确实利用了Python标准库中的工具(itertools.izip_longest),该工具旨在通过填充默认元素来处理压缩不等长度列表
import itertools
def mix(a, b):
a_rev = reversed(a)
b_rev = reversed(b)
if len(a) > len(b):
temp = itertools.izip_longest(a_rev, b_rev, fillvalue='spam')
elif len(b) > len(a):
temp = itertools.izip_longest(b_rev, a_rev, fillvalue='spam')
sequence = list()
for item in temp:
sequence.extend(item)
return sequence
o = mix([1, 2 ,3], ['A', 'B', 'C', 'D', 'E', 'F'])
o.reverse()
print(o)