Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/list/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python3仅基于索引的一个值对元组列表进行Uniquify_Python_List_Python 3.x_Tuples - Fatal编程技术网

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')]