我发誓我首先搜索了SO,发现了许多“可以工作 - 如果适应”,但没有什么真正帮助我。我所拥有的是一个元组列表:
[('', 'noreply@bookfresh.com'), ('Andrea', 'andrea@aaa.com'), ('Your Book', 'noreply@bookfresh.com'), ..]
在这种情况下,它是一个元组列表,在所有索引中都有一个“Name”作为第一个值,“Email”作为第二个值。并且列表没有以任何特定方式排序(尚未)。
我需要的是一个干净且易于理解(我不一定在寻找我甚至无法阅读的单行)的方式来制作一个“未加工的”列表,但是有这些规则/警告:
此最小化示例中的最终输出将是:
[('Andrea', 'andrea@aaa.com'), ('Your Book', 'noreply@bookfresh.com'), ..]
如果输出没有排序或排序并不重要,因为我知道如何排序未排序的元组列表。感谢
答案 0 :(得分:2)
方法#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')]
答案 1 :(得分:1)
您可以使用第二个条目作为关键字来构建字典。字典具有在其键中不包含任何重复的适当性。如果您在构建字典之前按第一个元素的长度排序,它将为您提供所需的内容:
your_list_sorted = sorted(your_list, key=lambda x: len(x[0]))
out = dict((v, k) for k, v in your_list_sorted)
如果您需要以列表形式输出,可以out_list = list(out.items())
来获取它。
答案 2 :(得分:0)
可能最简单的方法是使用这样的集合:
L = [('', 'noreply@bookfresh.com'), ('Andrea', 'andrea@aaa.com'), ('Your Book', 'noreply@bookfresh.com'), ..]
emails = set()
result_L = []
for item in L:
if item[1] in emails:
# this email address is already seen
continue
result_L += [item]
emails.add(item[1])
但是,如果你想保留最后一项,你可以使用它(最后,你可能想要反转result_L
):
for i in reversed(L):
# ...
还有很多其他方法可以做到这一点。例如,请考虑使用dict
:
result_dict = {}
for item in L:
result_dict[item[1]] = item[0]
result_L = [(y, x) for (x, y) in result_dict.items()]