>>> 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']
答案 0 :(得分:2)
由于您首先使用itertools
,我认为您希望这可以在任何迭代上工作,而不仅仅是列表,理想情况下,不要先急切地使用它们。否则,只需这样做:
list(itertools.chain.from_iterable(zip(a,b))) + a[len(b):] + b[len(a):]
zip_longest
函数几乎完成您想要的开箱即用的功能,但是一旦较短,它会为每个插槽插入一个fillvalue
(默认None
)迭代用尽了。如果您的值都是真实的,那么您可以使用if i
中的filter
或None
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']