Python嵌套列表内部比较和编辑
Posted
技术标签:
【中文标题】Python嵌套列表内部比较和编辑【英文标题】:Python nested list internal comparison and editing 【发布时间】:2015-01-26 15:41:21 【问题描述】:我一直在试图弄清楚,最简单的解释方法是使用示例:
a = [[1, 2, 4], [2, 5], [0, 3, 7, 8], [12, 3, 6], [18, 14]]
这是我开始的那种列表。 我需要最终得到一个列表,其中包含 a 中所有列表的列表,其中包含添加在一起的重叠元素。
result = [[1, 2, 4, 5], [0, 3, 6, 7, 8, 12], [14, 18]]
我该怎么办?
亲切的问候, 更快
【问题讨论】:
所有的subsists可以存储为列表吗? 子列表的数量事先不知道。 查看此问题的一种(可能是不必要的复杂)方法是找到二分图的连通分量,其中一组节点是a
的子列表,另一组是它们的条目.
@qqvc(通过suggested edit):请不要编辑问题以包含答案。将其发布为答案。
【参考方案1】:
a = [[1, 2, 4], [2, 5], [0, 3, 7, 8], [12, 3, 6], [18, 14]]
result = []
for s in a:
s = set(s)
for t in result:
if t & s:
t.update(s)
break
else:
result.append(s)
这将逐个遍历列表并从当前子列表 (s
) 创建一个集合。然后它会检查结果,如果有另一个集合 t
与它有一个非空的交集。如果是这种情况,来自s
的项目将添加到该集合t
。如果没有t
与非空交集,则s
是一个新的独立结果,可以追加到结果列表中。
这样的问题也是fixed-point iteration 的一个很好的例子。在这种情况下,您将查看列表并继续合并子列表,只要您仍然可以找到重叠的列表。您可以使用 itertools.combinations
查看子列表对来实现这一点:
result = [set(x) for x in a] # start with the original list of sets
fixedPoint = False # whether we found a fixed point
while not fixedPoint:
fixedPoint = True
for x, y in combinations(result, 2): # search all pairs …
if x & y: # … for a non-empty intersection
x.update(y)
result.remove(y)
# since we have changed the result, we haven’t found the fixed point
fixedPoint = False
# abort this iteration
break
【讨论】:
【参考方案2】:我能想到的一种方法是通过递归。从一个项目开始,然后循环,直到找到它所连接的每个数字。对于这些数字中的每一个,您都必须这样做。因此递归。为了提高效率,请将您访问过的数字存储在一个列表中,并在每个递归序列的开头进行检查,以确保您不会重复任何探索。
【讨论】:
【参考方案3】:两个班轮:
a_set = [set(x) for x in a]
result = [list(x.union(y)) for i,x in enumerate(a_set) for y in a_set[i:]
if x.intersection(y) and x != y]
【讨论】:
这会丢弃14, 18
,因为它不会与其他任何东西相交。
这对于列表列表也根本不起作用,其中 两个以上 列表相互重叠。例如[[1, 2], [2, 3], [3, 4]]
.
@poke,为什么要包含14, 18
?问题是“一个列表,其中包含 a 中所有列表的列表,其中包含添加在一起的重叠元素”。 14, 18
没有与另一个子列表重叠的元素。
如果您查看 OP 的示例,您可以清楚地看到 [14, 18]
包含在所需的输出中。结果应该是输入中的所有列表,但在有重叠元素的地方合并了这些子列表。【参考方案4】:
我为你留下了最后一步:
a = [[1, 2, 4], [2, 5], [0, 3, 7, 8], [12, 3, 6], [18, 14]]
result = [[1, 2, 4, 5], [0, 3, 6, 7, 8, 12], [14, 18]]
# each sub list
result2 = []
count = 0
print a
for sub_list in a:
print count
print "sub_list: " + str(sub_list)
a.pop(count)
print "a: " + str(a)
#each int
sub_list_extend_flag = False
for int_in_sub_list in sub_list:
print "int_in_sub_list: " + str(int_in_sub_list)
for other_sub_list in a:
print "current_other_sub_list: " + str(other_sub_list)
if int_in_sub_list in other_sub_list:
sub_list_extend_flag = True
other_sub_list.extend(sub_list)
result2.append(list(set(other_sub_list)))
if not sub_list_extend_flag:
result2.append(sub_list)
count += 1
print result2
【讨论】:
这给了我[[1, 2, 4, 5], [1, 2, 4, 5], [0, 3, 6, 7, 8, 12], [0, 3, 6, 7, 8, 12], [0, 3, 6, 7, 8, 12], [18, 14]]
,这不是我想要的结果。忽略结果中的重复列表,这也不适用于 两个以上 或 none 重叠的子列表列表。例如[[1, 2], [2, 3], [3, 4], [5, 6]]
.【参考方案5】:
简单回答:
a = [[1, 2, 4], [2, 5], [0, 3, 7, 8], [12, 3, 6], [18, 14]]
for x in a:
for y in x:
print y
它比第一个更简单:
box=[]
a = [[1, 2, 4], [2, 5], [0, 3, 7, 8], [12, 3, 6], [18, 14]]
for x in a:
for y in x:
box.append(y)
print box
结果:[1, 2, 4, 2, 5, 0, 3, 7, 8, 12, 3, 6, 18, 14]
有了这个,你可以比较数字:
box=[]
box2=""
a = [[1, 2, 4], [2, 5], [0, 3, 7, 8], [12, 3, 6], [18, 14]]
for x in a:
for y in x:
box.append(y)
print box
for a in box:
box2+=str(a)
print box2
结果: 12425037812361814
你也可以让它更可爱:
print " ".join(box2)
结果: 1 2 4 2 5 0 3 7 8 1 2 3 6 1 8 1 4
【讨论】:
以上是关于Python嵌套列表内部比较和编辑的主要内容,如果未能解决你的问题,请参考以下文章