我想在python中合并两个不同长度的列表,这样较短的列表中的元素在最终的列表中尽可能的等间距。也就是说,我想取[1, 2, 3, 4]
和['a','b']
并合并它们,得到一个类似于[1, 'a', 2, 3, 'b', 4]
的列表。它也需要能够处理不是精确倍数的列表。所以它可以取[1, 2, 3, 4, 5]
和['a', 'b', 'c']
,并产生[1, 'a', 2, 'b', 3, 'c', 4, 5]
或类似的结果,它需要保持两个列表的顺序。
我可以看到如何通过一个冗长的蛮力方法来做到这一点,但由于Python似乎有大量的优秀工具来做各种各样的聪明的事情,我不知道(还),我想知道是否有什么更优雅的我可以使用?
如果要在末尾保留多余的元素,请参见How to interleave two lists of different length?。
9条答案
按热度按时间9avjhtql1#
大量借鉴Jon Clements的解决方案,可以编写一个函数,接受任意数量的序列,并返回均匀间隔项的合并序列:
收益率
piwo6bdm2#
这基本上与Bresenham's line algorithm相同,您可以计算“像素”位置并将其用作列表的索引。
任务的不同之处在于每个元素只显示一次,需要修改算法或对索引进行后处理,只在元素第一次出现时追加列表中的元素,但有一点不明确:当两个像素/列表索引同时改变时,你需要选择先包含哪一个。这对应于问题和注解中提到的两个不同的列表交错选项。
sulc1iza3#
假设
a
是要插入的序列:mo49yndu4#
如果
a
是较长的列表而b
是较短的列表例如
您可以使用此技巧来确保
a
比b
长qaxu7uf25#
如果我们这样修改“乔恩”的回答
a
/b
中哪个最长并不重要uqjltbpv6#
如果我们想在没有itertools的情况下执行此操作:
啊,漏掉了等间距的部分。由于某种原因,这个问题被标记为重复,在不同的列表长度存在的情况下,这个问题不需要等间距。
ajsxfq5m7#
我喜欢unutbu's answer,但不喜欢嵌套样式,所以我重写了它。当我在那里的时候,我注意到排序不稳定,所以我用
operator.itemgetter
修复了它。我还用
enumerate
替换了itertools.count
,因为它更直观,而且它对大输入也更准确,虽然我还没有测试过。请注意,与第二个示例有一个不同之处,在第二个示例中,
'b'
和'c'
下移:juud5qan8#
@Jon Clements答案的变体,使用带解释的
more_itertools.collate
。这个答案已经更新,可以在Python 3中使用。
first
和second
是元组的可迭代,每个元组包括位置-元素对。more_itertools.collate()
Packageheapq.merge()
,它按顺序合并预先排序的first
和second
可迭代对象。在最终列表解析中,key
是排序函数,而返回每个元组中的最后一个元素。more_itertools.interleave_evenly()
基于前面提到的Bresenham算法。您必须确定输出是否是您想要的。heapq.merge()
并直接使用。通过
> pip install more_itertools
安装此第三方软件包noj0wjuj9#
此函数将生成任意数量列表的均匀混合,而不依赖于昂贵的
sort