[英]Python3 Uniquify list of tuples based on only one of the values of the index
我發誓我首先進行了搜索,發現很多“如果適應就可以工作”,但沒有什么真正幫助我的。 我所擁有的是以下形式的元組列表:
[('', 'noreply@bookfresh.com'), ('Andrea', 'andrea@aaa.com'), ('Your Book', 'noreply@bookfresh.com'), ..]
在這種情況下,它是一個元組列表,在所有索引中,元組的第一個值為“名稱”,第二個值為“ Email”。 並且列表沒有以任何特定方式排序(尚未)。
我需要一種干凈且易於理解的方法(我不一定要尋找連我都看不懂的單行)來生成“唯一化”列表,但要遵循以下規則/要求:
在此最小化示例中的最終輸出為:
[('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')]
您可以使用第二個條目作為關鍵字來構建字典。 字典具有在其鍵中不包含任何重復項的特性。 如果在構建字典之前按第一個元素的長度排序,它將為您提供所需的內容:
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())
來獲取它。
可能最簡單的方法是使用如下所示的集合:
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()]
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.