簡體   English   中英

Python3根據索引值之一唯一化元組列表

[英]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”。 並且列表沒有以任何特定方式排序(尚未)。

我需要一種干凈且易於理解的方法(我不一定要尋找連我都看不懂的單行)來生成“唯一化”列表,但要遵循以下規則/要求:

  • 僅當找到元組第二個值的重復項時才刪除該元組(在這種情況下,它恰好是一個電子郵件地址,並且將是“ noreply@bookfresh.com”)
  • 不要消除所有重復元組的實例。 我需要保留一個,保留的應該是具有第一個對象的len()最多的元組。 (在這種情況下,對於重復的元組,它將僅保留該元組(“您的書”,“ 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')]

您可以使用第二個條目作為關鍵字來構建字典。 字典具有在其鍵中不包含任何重復項的特性。 如果在構建字典之前按第一個元素的長度排序,它將為您提供所需的內容:

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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM