Skip to main content
 首页 » 编程设计

Python3 Uniquify 仅基于一个索引值的元组列表

2024年08月26日38yxwkf

我发誓我首先搜索了 SO,发现了很多“如果适应的话可以工作”,但没有什么能真正帮助我。我所拥有的是以下形式的元组列表:

[('', 'noreply@bookfresh.com'), ('Andrea', 'andrea@aaa.com'), ('Your Book', 'noreply@bookfresh.com'), ..] 

在这种情况下,它是一个元组列表,在所有索引中,第一个值是“Name”,第二个值是“Email”。并且列表没有以任何特定方式排序(还)。

我需要的是一种清晰易懂的方式(我不一定要寻找我什至无法阅读的单行代码)来生成“唯一”列表,但要遵循以下规则/注意事项:

  • 只有在发现元组的第二个值重复时才删除元组(在本例中,它恰好是一个电子邮件地址,它将是“noreply@bookfresh.com”)
  • 不要消除所有重复元组的实例。我需要保留一个,要保留的应该是第一个对象的len()最多的元组。 (在这种情况下,对于重复的元组,它只会保留元组 ('Your Book', 'noreply@bookfresh.com')。

此最小化示例中的最终输出为:

[('Andrea', 'andrea@aaa.com'), ('Your Book', 'noreply@bookfresh.com'), ..] 

如果输出未排序或未排序并不重要,因为我知道如何对未排序的元组列表进行排序。谢谢

请您参考如下方法:

方法#1:收集所有的名字

如果我们想要最容易理解的版本,而不是最流畅的版本,可能是类似

pairs = [('', 'noreply@bookfresh.com'), ('Andrea', 'andrea@aaa.com'), ('Your Book', 'noreply@bookfresh.com')] 
 
data = {} 
for name, email in pairs: 
    if email not in data: 
        data[email] = [] 
    data[email].append(name) 
 
output = [(email, max(data[email], key=len)) for email in data] 

会起作用。这将问题分为两部分:构建一个字典,以电子邮件地址为键,以可能的名称列表为值;并遍历所有电子邮件地址并获得最长的名称。

第一部分可以使用 setdefault 进行压缩,例如

for name, email in pairs: 
    data.setdefault(email, []).append(name) 

但并不是每个人都熟悉它。


方法#2:排序并使其唯一

或者,我们可以同时按电子邮件地址和姓名长度排序,然后根据只保留最后看到的键/值对的内容构建字典:

>>> pairs.sort(key=lambda x: (x[1], len(x[0]))) 
>>> data = {v: k for k,v in pairs} 
>>> [(v,k) for k,v in data.items()] 
[('Andrea', 'andrea@aaa.com'), ('Your Book', 'noreply@bookfresh.com')]