列表列表中的唯一字典?

时间:2017-06-01 13:37:49

标签: python dictionary duplicates list-comprehension nested-lists

我有一个名为matrix的列表,其中包含一些行。每个row都包含一些词典,每个词典可以包含在多行中。

我想生成一个名为dictionaries的列表,其中包含矩阵中的所有字典,但没有重复。我已经有了解决方案,但我想使用理解。

row1 = [{'NODE':1}, {'NODE':2}, {'NODE':3}]
row2 = [{'NODE':3}, {'NODE':4}, {'NODE':5}]
row3 = [{'NODE':4}, {'NODE':6}, {'NODE':7}]
matrix = [row1, row2, row3]

dictionaries = []
for row in matrix:
    for dictionary in row:
        items.append(dictionary) if dictionary not in dictionaries else None

print dictionaries
[{'NODE':1}, {'NODE':2}, {'NODE':3}, {'NODE':4}, {'NODE':5}, {'NODE':6}, {'NODE':7}]

我想要类似下面这样的东西,但它不起作用,因为我在创建它时不能要求检查列表:

dictionaries = [dictionary for row in matrix for dictionary in row if dictionary not in dictionaries]

字典键和值是原始的不可变对象,如字符串和整数。

3 个答案:

答案 0 :(得分:5)

您可以使用列表推导,但根据您的Python版本,使用带有生成器表达式的collections.OrderedDict object来展平矩阵实际上会更有效。

如果您的值不可用因此无法存储在集合或字典中,您必须首先使用创建不可变表示,因此我们可以存储在集合或字典中表示以有效地跟踪唯一性。

对于具有所有键和值不可变的扁平结构的字典,只需使用tuple(sorted(d.items()))。这会按排序顺序生成所有(key, value)对(也是元组)的元组,以避免字典顺序问题。

在Python 3.5及更高版本中,使用OrderedDict()将不可变键映射到原始词典:

from collections import OrderedDict

key = lambda d: tuple(sorted(d.items()))

dictionaries = list(OrderedDict((key(v), v) for row in matrix for v in row).values())

在Python 3.4及更早版本中,OrderedDict速度很慢,而且您不得不为Python 3.4及以下版本使用单独的set方法:

key = lambda d: tuple(sorted(d.items()))
seen = set()
seen_add = seen.add
dictionaries = [
    v for row in matrix
    for k, v in ((key(v), v) for v in row)
    if not (k in seen or seen_add(k))]

使用输入数据和OrderedDict

进行快速演示
>>> from collections import OrderedDict
>>> row1 = [{'NODE':1}, {'NODE':2}, {'NODE':3}]
>>> row2 = [{'NODE':3}, {'NODE':4}, {'NODE':5}]
>>> row3 = [{'NODE':4}, {'NODE':6}, {'NODE':7}]
>>> matrix = [row1, row2, row3]
>>> key = lambda d: tuple(sorted(d.items()))
>>> list(OrderedDict((key(v), v) for row in matrix for v in row).values())
[{'NODE': 1}, {'NODE': 2}, {'NODE': 3}, {'NODE': 4}, {'NODE': 5}, {'NODE': 6}, {'NODE': 7}]

答案 1 :(得分:1)

如果你有NumPy:

np.unique(matrix).tolist()

答案 2 :(得分:0)

展平列表,然后使用一套消除欺骗。

print set(item for sublist in matrix for item in sublist)