使用python从不同长度的元组列表中删除重复项

Posted

技术标签:

【中文标题】使用python从不同长度的元组列表中删除重复项【英文标题】:Remove duplicates from a list of tuples of different length with python 【发布时间】:2019-01-03 13:00:43 【问题描述】:

我使用正则表达式等从文本中提取特定名称。结果是包含标题和名称的元组列表。元组的长度可能不同。 lst 下面列出了可能的情况。我需要从结果中删除重复的名称。例如,('Lord', 'Justice') == ('Lord', 'Justice', 'Smith'), and ('Lady', 'Smiles') == ('Lady', 'Justice', ' Smiles'),但是 ('Lord', 'Justice', 'Smith') 和 ('Lady', 'Justice', 'Smiles') 是不同的名称。 lst 中每个元素的期望输出应该是 [('Lord', 'Justice', 'Smith'), ('Lady', 'Justice', 'Smiles')]

lst = [[('Lord', 'Justice', 'Smith'), ('Lady', 'Justice', 'Smiles')],
       [('Lord', 'Justice', 'Smith'), ('Lady', 'Justice', 'Smiles'), ('Lord', 'Justice')],
       [('Lord', 'Justice', 'Smith'), ('Lady', 'Smiles'), ('Lady', 'Justice', 'Smiles')],
       [('Lord', 'Justice', 'Smith'), ('Lady', 'Justice'), ('Lady', 'Justice', 'Smiles')],
       [('Lord', 'Justice', 'Smith'), ('Lady', 'Justice', 'Smiles'), ('Lady', 'Smiles')]]

这就是我现在所拥有的,但它没有产生所需的输出。非常感谢您的帮助和建议。

for l in lst:
    print(l)
    # remove duplicates based on the last index in tuples
    lst_1 = list(dict((v[-1],v) for v in sorted(l, key=lambda l: lst[0])).values())
    print(lst_1)
    # remove duplicates based on the second index [1] in tuples
    lst_2 = list(dict((v[1],v) for v in sorted(lst_1, key=lambda lst_1: lst_1[0])).values())    
    print(lst_2)
    print("\n")

更新:

我的示例可能过于具体。我必须包含其他名称,因此当存在其他名称时解决方案应该可以工作:

lst = [
[('Lord', 'Justice', 'Smith'), ('Lady', 'Justice', 'Smiles'), ('Lord', 'Other'), ('Lady', 'Another'), ('Lady', 'Diana', 'Spencer'), ('Lord', 'Dave', 'Castle')],
[('Lord', 'Justice', 'Smith'), ('Lady', 'Justice', 'Smiles'), ('Lord', 'Justice'), ('Lord', 'Other'), ('Lady', 'Another'), ('Lady', 'Diana', 'Spencer'), ('Lord', 'Dave', 'Castle')],
[('Lord', 'Justice', 'Smith'), ('Lady', 'Smiles'), ('Lady', 'Justice', 'Smiles'), ('Lord', 'Other'), ('Lady', 'Another'), ('Lady', 'Diana', 'Spencer'), ('Lord', 'Dave', 'Castle')],
[('Lord', 'Justice', 'Smith'), ('Lady', 'Justice'), ('Lady', 'Justice', 'Smiles'), ('Lord', 'Other'), ('Lady', 'Another'), ('Lady', 'Diana', 'Spencer'), ('Lord', 'Dave', 'Castle')],
[('Lord', 'Justice', 'Smith'), ('Lady', 'Justice', 'Smiles'), ('Lady', 'Smiles'), ('Lord', 'Other'), ('Lady', 'Another'), ('Lady', 'Diana', 'Spencer'), ('Lord', 'Dave', 'Castle')]
]

理想的输出:

[('Lord', 'Justice', 'Smith'), ('Lady', 'Justice', 'Smiles'), ('Lord', 'Other'), ('Lady', 'Another'), ('Lady', 'Diana', 'Spencer'), ('Lord', 'Dave', 'Castle')]
[('Lord', 'Justice', 'Smith'), ('Lady', 'Justice', 'Smiles'), ('Lord', 'Other'), ('Lady', 'Another'), ('Lady', 'Diana', 'Spencer'), ('Lord', 'Dave', 'Castle')]
[('Lord', 'Justice', 'Smith'), ('Lady', 'Justice', 'Smiles'), ('Lord', 'Other'), ('Lady', 'Another'), ('Lady', 'Diana', 'Spencer'), ('Lord', 'Dave', 'Castle')]
[('Lord', 'Justice', 'Smith'), ('Lady', 'Justice', 'Smiles'), ('Lord', 'Other'), ('Lady', 'Another'), ('Lady', 'Diana', 'Spencer'), ('Lord', 'Dave', 'Castle')]
[('Lord', 'Justice', 'Smith'), ('Lady', 'Justice', 'Smiles'), ('Lord', 'Other'), ('Lady', 'Another'), ('Lady', 'Diana', 'Spencer'), ('Lord', 'Dave', 'Castle')]

【问题讨论】:

('Justice', 'Lord')('Lord', 'Justice') 怎么样?那些是平等的吗? 根据名称的提取方式,这不应出现在结果中。标题永远是第一位的。 如果这里的实际意图是比较版本号,您应该知道这是solved problem(例如,使用元组而不是字符串)。 不是真的,我需要一个唯一名称列表,我必须在我的管道中进一步使用。 【参考方案1】:

您可以使用itertools.groupby轻松做到这一点

lst = [
[('Lord', 'Justice', 'Smith'), ('Lady', 'Justice', 'Smiles'), ('Lord', 'Other'), ('Lady', 'Another'), ('Lady', 'Diana', 'Spencer'), ('Lord', 'Dave', 'Castle')],
[('Lord', 'Justice', 'Smith'), ('Lady', 'Justice', 'Smiles'), ('Lord', 'Justice'), ('Lord', 'Other'), ('Lady', 'Another'), ('Lady', 'Diana', 'Spencer'), ('Lord', 'Dave', 'Castle')],
[('Lord', 'Justice', 'Smith'), ('Lady', 'Smiles'), ('Lady', 'Justice', 'Smiles'), ('Lord', 'Other'), ('Lady', 'Another'), ('Lady', 'Diana', 'Spencer'), ('Lord', 'Dave', 'Castle')],
[('Lord', 'Justice', 'Smith'), ('Lady', 'Justice'), ('Lady', 'Justice', 'Smiles'), ('Lord', 'Other'), ('Lady', 'Another'), ('Lady', 'Diana', 'Spencer'), ('Lord', 'Dave', 'Castle')],
[('Lord', 'Justice', 'Smith'), ('Lady', 'Justice', 'Smiles'), ('Lady', 'Smiles'), ('Lord', 'Other'), ('Lady', 'Another'), ('Lady', 'Diana', 'Spencer'), ('Lord', 'Dave', 'Castle')]
]
res = [[max(reversed(list(v)), key=len) for k,v in groupby(sl, lambda x: x[0])] for sl in lst]
for l in res:
    print(l)

输出

[('Lord', 'Justice', 'Smith'), ('Lady', 'Justice', 'Smiles'), ('Lord', 'Other'), ('Lady', 'Diana', 'Spencer'), ('Lord', 'Dave', 'Castle')]
[('Lord', 'Justice', 'Smith'), ('Lady', 'Justice', 'Smiles'), ('Lord', 'Other'), ('Lady', 'Diana', 'Spencer'), ('Lord', 'Dave', 'Castle')]
[('Lord', 'Justice', 'Smith'), ('Lady', 'Justice', 'Smiles'), ('Lord', 'Other'), ('Lady', 'Diana', 'Spencer'), ('Lord', 'Dave', 'Castle')]
[('Lord', 'Justice', 'Smith'), ('Lady', 'Justice', 'Smiles'), ('Lord', 'Other'), ('Lady', 'Diana', 'Spencer'), ('Lord', 'Dave', 'Castle')]
[('Lord', 'Justice', 'Smith'), ('Lady', 'Justice', 'Smiles'), ('Lord', 'Other'), ('Lady', 'Diana', 'Spencer'), ('Lord', 'Dave', 'Castle')]

【讨论】:

我的示例可能过于具体。我必须包含其他名称,因此当存在其他名称时,解决方案应该可以工作。我更新了我的问题。 @aviss。更新了答案;让我知道这是否有帮助 完美!非常感谢!【参考方案2】:

我提出了这个解决方案:

from itertools import chain, groupby

lst = [
[('Lord', 'Justice', 'Smith'), ('Lady', 'Justice', 'Smiles')],
[('Lord', 'Justice', 'Smith'), ('Lady', 'Justice', 'Smiles'), ('Lord', 'Justice')],
[('Lord', 'Justice', 'Smith'), ('Lady', 'Smiles'), ('Lady', 'Justice', 'Smiles')],
[('Lord', 'Justice', 'Smith'), ('Lady', 'Justice'), ('Lady', 'Justice', 'Smiles')],
[('Lord', 'Justice', 'Smith'), ('Lady', 'Justice', 'Smiles'), ('Lady', 'Smiles')]
]

def remove_duplicates(lst):
    rv = []
    for g, v in groupby([g for g, _ in groupby(sorted(lst))], key=lambda v: v[0]):
        rv.append(max(list(v), key=lambda v: len(v)))
    return rv


for option in lst:
    print(remove_duplicates(option))

输出:

[('Lady', 'Justice', 'Smiles'), ('Lord', 'Justice', 'Smith')]
[('Lady', 'Justice', 'Smiles'), ('Lord', 'Justice', 'Smith')]
[('Lady', 'Justice', 'Smiles'), ('Lord', 'Justice', 'Smith')]
[('Lady', 'Justice', 'Smiles'), ('Lord', 'Justice', 'Smith')]
[('Lady', 'Justice', 'Smiles'), ('Lord', 'Justice', 'Smith')]

【讨论】:

lst 是从文本中提取名称时我可能拥有的不同选项的列表。所以我需要一个脚本,它会为所有这些选项输出相同的结果。 @aviss 我修改了答案 我的示例可能过于具体。我必须包含其他名称,因此当存在其他名称时,解决方案应该可以工作。我更新了我的问题。

以上是关于使用python从不同长度的元组列表中删除重复项的主要内容,如果未能解决你的问题,请参考以下文章

如何从python中的列表中删除重复的元组?

Python - 验证列表中的元组具有相同的长度

如何根据元组的索引值从列表中删除重复的元组,同时保持元组的顺序? [复制]

Python中dict的元组列表[重复]

python中的元组和列表有啥区别,哪个更有效[重复]

删除元组列表中包含 nan 的元组——Python