我正在檢索 ( name, id) 對的串列,我需要確保沒有重復的name,無論id.
# Sample data
filesID = [{'name': 'file1', 'id': '353'},{'name': 'file2', 'id': '154'},{'name': 'file3', 'id': '1874'},{'name': 'file1', 'id': '14'}]
我設法通過嵌套回圈獲得所需的輸出:
uniqueFilesIDLoops = []
for pair in filesID:
found = False
for d in uniqueFilesIDLoops:
if d['name'] == pair['name']:
found = True
if not found:
uniqueFilesIDLoops.append(pair)
但我無法讓它與串列理解一起作業......這是我迄今為止嘗試過的:
uniqueFilesIDComprehension = []
uniqueFilesIDComprehension = [pair for pair in filesID if pair['name'] not in [d['name'] for d in uniqueFilesIDComprehension]]
輸出:
# Original data
[{'name': 'file1', 'id': '353'}, {'name': 'file2', 'id': '154'}, {'name': 'file3', 'id': '1874'}, {'name': 'file1', 'id': '14'}]
# Data obtained with list comprehension
[{'name': 'file1', 'id': '353'}, {'name': 'file2', 'id': '154'}, {'name': 'file3', 'id': '1874'}, {'name': 'file1', 'id': '14'}]
# Data obtained with loops (and desired output)
[{'name': 'file1', 'id': '353'}, {'name': 'file2', 'id': '154'}, {'name': 'file3', 'id': '1874'}]
我在想,可能對uniqueFilesIDComprehension串列理解內部的呼叫在每次迭代時都沒有更新,因此使用[]而不是找到相應的值......
uj5u.com熱心網友回復:
您無法在創建串列理解的程序中訪問其內容,因為只有在其值被完全評估后才會將其分配給任何內容。
洗掉重復項的最簡單方法是:
list({el['name'] : el for el in filesID}.values())- 這將根據每個元素的名稱創建一個字典,因此每次遇到重復名稱時,它都會用新元素覆寫它。創建 dict 后,您需要做的就是獲取值并將其轉換為list. 如果您想保留每個名稱的第一個元素,而不是最后一個元素,您可以通過在 for 回圈中創建字典來代替:
out = {}
for el in filesID:
if el['name'] not in out:
out[el['name']] = el
最后,在實施任何這些解決方案時要考慮的一件事——既然你不關心id部分,你真的需要提取它嗎?
我會問自己這是否也不是一個有效的選擇。
out = {el['name'] for el in filesID}
print(out)
輸出:{'file1', 'file3', 'file2'}
uj5u.com熱心網友回復:
我會堅持使用您的原始回圈,但請注意它可以變得更清潔。即,您不需要名為found.
uniqueFilesIDLoops = []
for pair in filesID:
for d in uniqueFilesIDLoops:
if d['name'] == pair['name']:
break
else:
uniqueFilesIDLoops.append(pair)
您還可以使用輔助集來簡化重復名稱的檢測(因為它們是str值,因此是可散列的)。
seen = set()
uniqueFilesIDLoops = []
for pair in filesID:
if (name := pair['name']) not in seen:
seen.add(name)
uniqueFilesIDLoops.append(pair)
因為我們現在已經將結果與我們在其中執行查找的資料結構分離,所以可以通過撰寫一個運算式將上述結果轉換為串列推導式,該運算式在名稱不在集合中時回傳 True 并將名稱添加到集合中。有點像
seen = set()
uniqueFilesIDLoops = [pair
for pair in filesID
if (pair['name'] not in seen
and (seen.add(pair['name']) or True))]
(seen.add總是回傳None,這是一個錯誤的值,所以seen.add(...) or True總是True。)
uj5u.com熱心網友回復:
串列推導式用于創建新串列,因此原始串列永遠不會更新;賦值導致變數參考新創建的串列。
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/436651.html
