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嵌套列表内部比较和编辑的主要内容,如果未能解决你的问题,请参考以下文章

python中的列表操作

使用 Itertools 具有内部中断的可变级别的嵌套循环

SwiftUI 嵌套列表不出现

Python入门-5函数:09嵌套函数(内部函数)-数据隐藏

Python嵌套函数和闭包

在类中如何实现类的嵌套