Python3仅基于索引的一个值对元组列表进行Uniquify
我发誓我是这么先搜索的,找到了很多“如果改编可以工作”,但没有任何东西真正帮助我。我有一个元组列表,格式如下:Python3仅基于索引的一个值对元组列表进行Uniquify,python,list,python-3.x,tuples,Python,List,Python 3.x,Tuples,我发誓我是这么先搜索的,找到了很多“如果改编可以工作”,但没有任何东西真正帮助我。我有一个元组列表,格式如下: [(“”,'noreply@bookfresh.com","安德里亚",andrea@aaa.com你的书noreply@bookfresh.com'), ..] 在本例中,它是一个元组列表,在所有索引中,第一个值是“Name”,第二个值是“Email”。而且列表并没有以任何特定的方式排序(目前) 我需要的是一种清晰易懂的方法(我不一定要找一行我甚至看不懂的)来生成一个“非限定”列表
[(“”,'noreply@bookfresh.com","安德里亚",andrea@aaa.com你的书noreply@bookfresh.com'), ..]
在本例中,它是一个元组列表,在所有索引中,第一个值是“Name”,第二个值是“Email”。而且列表并没有以任何特定的方式排序(目前)
我需要的是一种清晰易懂的方法(我不一定要找一行我甚至看不懂的)来生成一个“非限定”列表,但有以下规则/注意事项:
- 只有在发现元组第二个值的重复项时才删除元组(在本例中,它恰好是一个电子邮件地址,应该是“noreply@bookfresh.com))
- 不要消除所有重复元组的实例。我需要保留一个,要保留的应该是第一个对象中len()最多的元组。(在这种情况下,在重复的元组中,它将只保留元组('yourbook','noreply@bookfresh.com")
不管输出是否排序,因为我知道如何对未排序的元组列表进行排序。谢谢,最简单的方法可能是使用如下集合:
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])
但是,如果您想保留最后一项,您可以使用此选项(最后,您可能希望反转结果\u L
):
<> P.>还有很多其他的方法来做这件事。例如,考虑使用<代码> DICT<代码>:
result_dict = {}
for item in L:
result_dict[item[1]] = item[0]
result_L = [(y, x) for (x, y) in result_dict.items()]
您可以使用第二个条目作为键来构建词典。词典的键中不包含任何重复项是合适的。如果在构建词典之前按第一个元素的长度排序,它将为您提供所需的:
your_list_sorted = sorted(your_list, key=lambda x: len(x[0]))
out = dict((v, k) for k, v in your_list_sorted)
如果您需要列表形式的输出,您可以执行out\u list=list(out.items())
来获取它。方法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')]
感谢您对这两种方法的解释,这有助于想象问题试图抽象自己。我正在实现#2,尽管它完成了工作,谢谢:)我最终使用了下面@DSM提出的类似方法,它使用字典。但在你的例子中,它反过来了,所以这是一个额外的步骤。但是你的答案显然也有效,所以+1。
for name, email in pairs:
data.setdefault(email, []).append(name)
>>> 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')]