我发誓我首先搜索了 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')]
