【发布时间】:2020-04-13 10:58:58
【问题描述】:
我在编程方面还有些稚嫩,遇到了一个绊脚石。
我有一个列表列表,我想组合嵌套列表中具有相似元素的元素。
列表列表:
x = [[25, 26],[26, 27],[27, 28],[32, 33],[33, 34],[40, 41],[61, 62],[62, 63],[63, 64]]
我正在寻找的输出:
[[25,26,27,28],[32,33,34],[40,41],[61,62,63,64]]
我使用 lambda 函数、map、reduce 和 map-reduce 以几种不同的方式解决了这个问题。
我尝试过使用交集的 lambda 函数进行映射,但它没有捕获 2 以上的所有元素。即。 x[0] 与 x[2] 没有交集
map-reduce 只给了我第一个集合和最后一个索引,我可以迭代这个,但是看起来很麻烦,它也会跳过没有类似相交子列表的子列表。 (下例)
mapped = [(idx, i) for idx, i in enumerate(x)]
reduce(lambda a,b: a if not set(a[1]).intersection(set(b[1])) else (a[0]+b[0],set(a[1]).union(set(b[1]))) ,mapped)
输出:
(3, {25, 26, 27, 28})
任何帮助将不胜感激,谢谢!
【问题讨论】:
-
第一个问题:“相似”是一个模糊的术语。看来您的意思是 [[a,b],[b,c]] 形式的对,其中 c-b == b-a == 1。这是正确的吗?如果不是,你能定义“相似”吗?
-
第二个问题:在你呈现数据的时候,要合并的子列表都是相邻且连续的。我们是否可以假设这通常是正确的,或者我们应该考虑到对的任意排序?
-
嗨!是的,谢谢你的召唤。所有子列表都将按顺序排列。它们实际上是另一个文本行列表的索引,它们需要按顺序组合。要组合的子列表将彼此相邻并且“相似”,我的意思是前面的元素 x[n+1][0] == x[n][-1],并且当组合时每个子列表将是唯一序列号的列表。
-
在这种情况下,在我看来,您的第一步是丢弃每对的第二个元素,因为这只是分散注意力,它会为您提供类似
[25, 26, 27, 32, 33, 40, 61, 62, 63]的列表。现在您只需在不连续点将其划分为子列表,并在每个子列表的末尾添加一个额外的“页面”。使用高阶函数(即 itertools)可能有一种可爱的方法可以做到这一点,但它也是一个简单的函数。 -
或者,在概念上可能更简单,将列表展平,对其进行设置,并对结果进行排序。这当然不会更有效,但它可能会产生更清晰的代码,这通常更重要。
标签: python-3.x dictionary reduce