Lim*_*aaf 135 python dictionary
假设我有一个词典列表:
[
{'id': 1, 'name': 'john', 'age': 34},
{'id': 1, 'name': 'john', 'age': 34},
{'id': 2, 'name': 'hanna', 'age': 30},
]
Run Code Online (Sandbox Code Playgroud)
我需要获取一个唯一的字典列表(删除重复的字典):
[
{'id': 1, 'name': 'john', 'age': 34},
{'id': 2, 'name': 'hanna', 'age': 30},
]
Run Code Online (Sandbox Code Playgroud)
任何人都可以帮助我在Python中实现这一目标的最有效方法吗?
Joh*_*ooy 214
所以制作一个临时词典,关键是id
.这会过滤掉重复项.在values()
该字典中会列表
在Python2.7中
>>> L=[
... {'id':1,'name':'john', 'age':34},
... {'id':1,'name':'john', 'age':34},
... {'id':2,'name':'hanna', 'age':30},
... ]
>>> {v['id']:v for v in L}.values()
[{'age': 34, 'id': 1, 'name': 'john'}, {'age': 30, 'id': 2, 'name': 'hanna'}]
Run Code Online (Sandbox Code Playgroud)
在Python3中
>>> L=[
... {'id':1,'name':'john', 'age':34},
... {'id':1,'name':'john', 'age':34},
... {'id':2,'name':'hanna', 'age':30},
... ]
>>> list({v['id']:v for v in L}.values())
[{'age': 34, 'id': 1, 'name': 'john'}, {'age': 30, 'id': 2, 'name': 'hanna'}]
Run Code Online (Sandbox Code Playgroud)
在Python2.5/2.6中
>>> L=[
... {'id':1,'name':'john', 'age':34},
... {'id':1,'name':'john', 'age':34},
... {'id':2,'name':'hanna', 'age':30},
... ]
>>> dict((v['id'],v) for v in L).values()
[{'age': 34, 'id': 1, 'name': 'john'}, {'age': 30, 'id': 2, 'name': 'hanna'}]
Run Code Online (Sandbox Code Playgroud)
ste*_*eha 70
找到集合中常见元素的常用方法是使用Python的set
类.只需将所有元素添加到集合中,然后将集合转换为a list
,bam重复项就会消失.
当然,问题是a set()
只能包含hashable条目,而a dict
不可清除.
如果我有这个问题,我的解决方案是将每个dict
转换为表示的字符串dict
,然后将所有字符串添加到a set()
然后读出字符串值作为a list()
并转换回dict
.
dict
字符串形式的良好表示是JSON格式.Python有一个内置的JSON模块(json
当然称为).
剩下的问题是a中的元素dict
没有排序,当Python将其转换dict
为JSON字符串时,您可能会得到两个代表等效字典但不是相同字符串的JSON字符串.简单的解决方案是sort_keys=True
在您打电话时传递参数json.dumps()
.
编辑:这个解决方案假设给定的dict
任何部分可能有所不同.如果我们可以假设,每一个dict
具有相同"id"
的值将匹配所有其它dict
具有相同"id"
的值,那么这是矫枉过正; @ gnibbler的解决方案将更快更容易.
编辑:现在AndréLima明确表示,如果ID是重复的,可以安全地假设整个dict
是重复的.所以这个答案是矫枉过正的,我建议@ gnibbler的回答.
bub*_*ble 18
您可以使用numpy库(仅适用于Python2.x):
import numpy as np
list_of_unique_dicts=list(np.unique(np.array(list_of_dicts)))
Run Code Online (Sandbox Code Playgroud)
Sin*_*ina 18
如果字典仅由所有项唯一标识(ID不可用),则可以使用JSON使用答案.以下是不使用JSON的替代方法,只要所有字典值都是不可变的,它就会起作用
[dict(s) for s in set(frozenset(d.items()) for d in L)]
Run Code Online (Sandbox Code Playgroud)
Gre*_* E. 16
这是一个相当紧凑的解决方案,虽然我怀疑不是特别有效(温和地说):
>>> ds = [{'id':1,'name':'john', 'age':34},
... {'id':1,'name':'john', 'age':34},
... {'id':2,'name':'hanna', 'age':30}
... ]
>>> map(dict, set(tuple(sorted(d.items())) for d in ds))
[{'age': 30, 'id': 2, 'name': 'hanna'}, {'age': 34, 'id': 1, 'name': 'john'}]
Run Code Online (Sandbox Code Playgroud)
我们可以做pandas
import pandas as pd
yourdict=pd.DataFrame(L).drop_duplicates().to_dict('r')
Out[293]: [{'age': 34, 'id': 1, 'name': 'john'}, {'age': 30, 'id': 2, 'name': 'hanna'}]
Run Code Online (Sandbox Code Playgroud)
请注意与接受答案略有不同。
drop_duplicates
将检查 pandas 中的所有列,如果全部相同则该行将被删除。
例如 :
如果我们将第二个dict
名字从约翰改为彼得
L=[
{'id': 1, 'name': 'john', 'age': 34},
{'id': 1, 'name': 'peter', 'age': 34},
{'id': 2, 'name': 'hanna', 'age': 30},
]
pd.DataFrame(L).drop_duplicates().to_dict('r')
Out[295]:
[{'age': 34, 'id': 1, 'name': 'john'},
{'age': 34, 'id': 1, 'name': 'peter'},# here will still keeping the dict in the out put
{'age': 30, 'id': 2, 'name': 'hanna'}]
Run Code Online (Sandbox Code Playgroud)
小智 8
在 python 3 中,简单的技巧,但基于唯一字段(id):
data = [ {'id': 1}, {'id': 1}]
list({ item['id'] : item for item in data}.values())
Run Code Online (Sandbox Code Playgroud)
因为id
它足以检测重复项,并且id
可以清除:通过具有id
关键字的字典运行它们.每个键的值是原始字典.
deduped_dicts = dict((item["id"], item) for item in list_of_dicts).values()
Run Code Online (Sandbox Code Playgroud)
在Python 3中,values()
不返回列表; 你需要将整个表达式的右侧包裹起来list()
,并且你可以更经济地将表达的内容写成字典理解:
deduped_dicts = list({item["id"]: item for item in list_of_dicts}.values())
Run Code Online (Sandbox Code Playgroud)
请注意,结果可能与原始顺序不同.如果这是一个要求,你可以使用a Collections.OrderedDict
而不是a dict
.
顺便说一下,将数据保存在使用id
as键开头的字典中可能很有意义.
我总结了我最喜欢尝试的:
https://repl.it/@SmaMa/Python-List-of-unique-dictionaries
# ----------------------------------------------
# Setup
# ----------------------------------------------
myList = [
{"id":"1", "lala": "value_1"},
{"id": "2", "lala": "value_2"},
{"id": "2", "lala": "value_2"},
{"id": "3", "lala": "value_3"}
]
print("myList:", myList)
# -----------------------------------------------
# Option 1 if objects has an unique identifier
# -----------------------------------------------
myUniqueList = list({myObject['id']:myObject for myObject in myList}.values())
print("myUniqueList:", myUniqueList)
# -----------------------------------------------
# Option 2 if uniquely identified by whole object
# -----------------------------------------------
myUniqueSet = [dict(s) for s in set(frozenset(myObject.items()) for myObject in myList)]
print("myUniqueSet:", myUniqueSet)
# -----------------------------------------------
# Option 3 for hashable objects (not dicts)
# -----------------------------------------------
myHashableObjects = list(set(["1", "2", "2", "3"]))
print("myHashAbleList:", myHashableObjects)
Run Code Online (Sandbox Code Playgroud)
a = [
{'id':1,'name':'john', 'age':34},
{'id':1,'name':'john', 'age':34},
{'id':2,'name':'hanna', 'age':30},
]
b = {x['id']:x for x in a}.values()
print(b)
Run Code Online (Sandbox Code Playgroud)
输出:
[{'age':34,'id':1,'name':'john'},{'age':30,'id':2,'name':'hanna'}]
这里已经有很多答案了,我再补充一个:
import json
from typing import List
def dedup_dicts(items: List[dict]):
dedupped = [ json.loads(i) for i in set(json.dumps(item, sort_keys=True) for item in items)]
return dedupped
items = [
{'id': 1, 'name': 'john', 'age': 34},
{'id': 1, 'name': 'john', 'age': 34},
{'id': 2, 'name': 'hanna', 'age': 30},
]
dedup_dicts(items)
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
85281 次 |
最近记录: |