在python中混合两个不对称列表

时间:2018-03-26 03:03:13

标签: python algorithm list

>>> import itertools
>>> a = ['1', '2', '3', '4', '5']
>>> b = ['a', 'b', 'c', 'd', 'e', 'f']
>>> list(itertools.chain.from_iterable(zip(a,b)))
['1', 'a', '2', 'b', '3', 'c', '4', 'd', '5', 'e']

正如你所看到的,我有两个不对称的列表,我想像上面那样混合它们。问题是它忽略了最后一项。

预期: ['1', 'a', '2', 'b', '3', 'c', '4', 'd', '5', 'e', 'f']

实际值: ['1', 'a', '2', 'b', '3', 'c', '4', 'd', '5', 'e']

5 个答案:

答案 0 :(得分:2)

由于您首先使用itertools,我认为您希望这可以在任何迭代上工作,而不仅仅是列表,理想情况下,不要先急切地使用它们。否则,只需这样做:

list(itertools.chain.from_iterable(zip(a,b))) + a[len(b):] + b[len(a):]

zip_longest函数几乎完成您想要的开箱即用的功能,但是一旦较短,它会为每个插槽插入一个fillvalue(默认None)迭代用尽了。如果您的值都是真实的,那么您可以使用if i中的filterNone None作为谓词来过滤掉这些值,但是如果您的值可以是任何值在Python中,即使是_sentinel = object() [elem for elem in itertools.chain.from_iterable(itertools.zip_longest(a, b, fillvalue=_sentinel)) if elem is not _sentinel] ,唯一的方法就是变得非常笨重:

zip_longest

但是你可以看看list(itertools.chain.from_iterable(zip_longest_nofill(a, b))) 如何运作并自己做同样的事情,只产生"不完整"元组而不是"填充"元组,然后像这样调用它:

zip_longest

虽然从文档中提取def zip_longest_nofill(*args): empty = object() its = [iter(arg) for arg in args] while True: vals = (next(it, empty) for it in its) tup = tuple(val for val in vals if val is not empty) if not tup: return yield tup 代码的变体很容易在SO答案中解释但是有点挑战,所以使用显式循环可能更好:

zip_longest_nofill

我认为这个版本更容易理解(虽然实际上写起来有点难......)

当然,如果您唯一要使用flattened_zip_nofill来实现tinymce.init({ selector: 'textarea', plugins: 'equationeditor', content_css: '/path/to/mathquill.css', toolbar: [ 'bold italic underline | bullist numlist | subscript superscript | equationeditor' ], }); ,那么将其内联到扁平化部分会更容易,在这一点上你最后基本上是最后一节的双线。

答案 1 :(得分:1)

而不是chain,请使用zip_longest

import itertools
a = ['1', '2', '3', '4', '5']
b = ['a', 'b', 'c', 'd', 'e', 'f']
new_results = [i for b in itertools.zip_longest(a, b) for i in b if i is not None]

输出:

['1', 'a', '2', 'b', '3', 'c', '4', 'd', '5', 'e', 'f']

答案 2 :(得分:0)

只需手动附加剩余的:

def mix(a, b):
    c = list(itertools.chain.from_iterable(zip(a,b)))
    c += a[len(b)] + b[len(a):]
    return c

一个班轮:

mix = lambda a, b: list(itertools.chain.from_iterable(zip(a,b))) + a[len(b)] + b[len(a):]

答案 3 :(得分:0)

这应该有用,但不是很优雅

lst = []
for i in range(temp = max(len(a), len(b))):
    if i < len(a): lst.append(a[i])
    if i < len(b): lst.append(b[i])

lst

答案 4 :(得分:0)

您可以尝试使用itertools zip_longest:

a = ['1', '2', '3', '4', '5']
b = ['a', 'b', 'c', 'd', 'e', 'f']

import itertools

output=[]
for i in itertools.zip_longest(a,b):
    if i[0]==None:
        output.append(i[1])
    else:
        output.extend([i[0],i[1]])

print(output)

输出:

['1', 'a', '2', 'b', '3', 'c', '4', 'd', '5', 'e', 'f']