组关联python列表中的项目

时间:2017-05-30 23:04:45

标签: python python-3.x

我有以下表格的清单清单:

list = [ [['item1'], ['property1','property2','property3']], [['item2'],['property1', 'property4']], ..., [['itemN'],['property5']]]

我想构建另一个列表列表,其中所有上述项目与他们共享至少一个属性的项目组合在一起。例如:

new_list = [['item1','item2'], .., ['itemN']]

请注意,即使项目间接共享属性,也应将它们组合在一起。如果是item1与item2具有公共属性,该公共属性与item3具有公共属性,而item1不与item3共享任何属性,它们应该仍然全部组合在一起。

我的尝试是在原始列表中添加了一个布尔值(这样如果不需要我就不会重新迭代)并使用下面的函数:

list = [ [['item1'], ['property1','property2','property3'], True], [['item2'],['property1', 'property4'], True], [['itemN'],['property5'], True]]

def group_correlates(list):
    result = []
    for i, entry in enumerate(list):
        correlates = []
        items = entry[0]
        properties = entry[1]
        if entry[2]: # if not already grouped (True)
            correlates.append(items)
        for j, other_entry in enumerate(list):
            flag = other_entry[2]
            if not i == j:
                if flag:
                    other_properties = other_entry[1]
                    other_items = other_entry[0]
                    for property in properties:
                        if property in other_properties:
                            other_entry[2] = False # do not visit again
                            correlates.append(other_items)
                            result.append(correlates)
    return result

但我明白了:

[[['item1'], ['item2']], [['item1']]]

即使我能这样做,我相信有更优雅的方式来实现同样的目标

3 个答案:

答案 0 :(得分:1)

为什么不使用dict然后使用groupby模块中的itertools

这是一个如何做到这一点的例子:

from itertools import groupby

data = [[['item1'], ['property1','property2','property3']], [['item2'],['property1', 'property4']], [['itemN'],['property5']]]

aa = {}
for k, v in data:
    for j in v:
        try:
            aa[j] += k
        except KeyError:
            aa[j] = k


new_list = [k for k,_ in groupby(sorted(aa.values()), lambda x: x)]
print(new_list)

或者,您可以使用defaultdict模块中的collections

from collections import defaultdict
from itertools import groupby

data = [[['item1'], ['property1','property2','property3']], [['item2'],['property1', 'property4']], [['itemN'],['property5']]]

bb = defaultdict(None)

for k, v in data:
    for j in v:
        bb[j] = k


new_list = [k for k,_ in groupby(sorted(bb.values()), lambda x: x)]
print(new_list) 

两者都会输出:

[['item1', 'item2'], ['item2'], ['itemN']]

答案 1 :(得分:1)

首先将您的列表转换为所提及的字典。

list1 = [ [['item1'], ['property1','property2','property3']], 
          [['item2'], ['property1', 'property4']],
          [['item3'], ['property5', 'property6']]
        ]

dict1 = {item[0][0]: item[1] for item in list1}

然后:

new_list = []

for key in dict1:
    target = dict1[key]
    for k, v in dict1.items():
        if k != key and len(set(target).intersection(set(v))) != 0:
            new_list.append([key, k])
    new_list = [sorted(i) for i in new_list] # sort sublists
    new_list = [list(t) for t in set(map(tuple, new_list))] # remove dupes

flat = [item for sublist in new_list for item in sublist] # flatten list
unique = list(set(dict1.keys()).difference(set(flat)))
new_list.append(unique) # add unique keys

new_list
Out[76]: [['item1', 'item2'], ['item3']]

答案 2 :(得分:0)

"偶"主要是命名法。重点是你要找到连接的子图。

将所有嵌套列表放入"打开"列表...您需要处理此列表中的所有内容。当它空了,你就完成了。 开始一个新的子图列表 - 这是"列表列表"你提到过。

将项目列表和属性列表初始化为空列表。

选择一个项目并将其放入子图表列表中。现在,在属性和项目之间切换,直到没有添加任何内容:

  1. 对于刚刚添加的每个新项目(第一次只有初始项目),添加(到属性列表)该项目的所有属性。保留属性列表中新属性的列表。
  2. 从您的"打开"删除这些项目(及其属性)列表。
  3. 对于刚添加的每个属性,添加(到项目列表)具有该属性的每个项目。保留刚刚添加的项目列表。
  4. 重复步骤1-3,直到没有添加任何新内容。
  5. 此时,项目列表和属性列表描述了一个封闭的子图。将该对添加到子图的主列表中。

    返回,将项目和属性列表重置为空列表,然后从新的初始项目开始。继续这个,直到你用完所有物品。 "打开"列表现在是空的;所有项目和属性现在都显示在子图列表中。