如果这些字典对特定键具有相同的值,如何从列表中提取字典
How to extract dicts from list if these dicts have the same value for a specific key
我有一个这样的字典列表
list = [
{
"a": "1",
"b": "2",
"c": "3"
},
{
"a": "4",
"b": "2",
"c": "6"
},
{
"a": "7",
"b": "8",
"c": "9"
},
{
"a": "10",
"b": "11",
"c": "12"
},
{
"a": "13",
"b": "8",
"c": "15"
}
]
我的目标是提取此列表中键“b”具有相同“值”的所有字典。
在我的示例中它将是:
list_duplicates = [
{
"a": "1",
"b": "2",
"c": "3"
},
{
"a": "4",
"b": "2",
"c": "6"
},
{
"a": "7",
"b": "8",
"c": "9"
},
{
"a": "13",
"b": "8",
"c": "15"
}
]
我该如何执行此操作?
也许我可以使用反向逻辑:删除列表中“b”键不重复的所有字典?
查找重复项的一种非常标准的方法是使用 Counter
(您可以使用普通的字典和循环,但 Counter
使它更容易),然后使用 Counter
过滤项目计数大于 1。
>>> my_list = [
... {
... "a": "1",
... "b": "2",
... "c": "3"
... },
... {
... "a": "4",
... "b": "2",
... "c": "6"
... },
... {
... "a": "7",
... "b": "8",
... "c": "9"
... },
... {
... "a": "10",
... "b": "11",
... "c": "12"
... },
... {
... "a": "13",
... "b": "8",
... "c": "15"
... }
... ]
>>> from collections import Counter
>>> b_counts = Counter(d["b"] for d in my_list)
>>> list_duplicates = [d for d in my_list if b_counts[d["b"]] > 1]
>>> list_duplicates
[{'a': '1', 'b': '2', 'c': '3'}, {'a': '4', 'b': '2', 'c': '6'}, {'a': '7', 'b': '8', 'c': '9'}, {'a': '13', 'b': '8', 'c': '15'}]
这是使用 itertools.groupby
、itertools.chain
和 filter
的功能版本:
from itertools import groupby, chain
list(chain(*filter(lambda x: len(x)>1,
(list(g) for k,g in groupby(sorted(lst, key=lambda d: d['b']),
key=lambda d: d['b']))
)))
解释:groupby
'b' 的值(为此字典必须按此键排序),然后 filter
每个大小的组,最后 chain
输出形成一个列表。
注意。我将列表命名为 lst,以免与 list
内置
冲突
输出:
[{'a': '1', 'b': '2', 'c': '3'},
{'a': '4', 'b': '2', 'c': '6'},
{'a': '7', 'b': '8', 'c': '9'},
{'a': '13', 'b': '8', 'c': '15'}]
这种方法基本上创建了一个散列图,提供了索引列表,其中存在不同的键值。这里的关键是lst
中'b'对应的值。
所以基本上 countMap
看起来像这样:
{'2': [0, 1], '8': [2, 4], '11': [3]}
据此,我们可以创建输出列表,它仅附加原始列表中键值重复的索引。
countMap = {}
for i in range(len(lst)):
val = lst[i]['b']
if countMap.get(val) is not None:
countMap[val].append(i)
else:
countMap[val] = [i]
output = []
for i in countMap.keys():
if len(countMap[i]) > 1:
for j in countMap[i]:
output.append(lst[j])
print(output)
输出
[{'a': '1', 'b': '2', 'c': '3'}, {'a': '4', 'b': '2', 'c': '6'}, {'a': '7', 'b': '8', 'c': '9'}, {'a': '13', 'b': '8', 'c': '15'}]
有列表理解:
>>> [d for d in lst if len([di for di in lst if di["b"]==d["b"]])>1]
[{'a': '1', 'b': '2', 'c': '3'},
{'a': '4', 'b': '2', 'c': '6'},
{'a': '7', 'b': '8', 'c': '9'},
{'a': '13', 'b': '8', 'c': '15'}]
我有一个这样的字典列表
list = [
{
"a": "1",
"b": "2",
"c": "3"
},
{
"a": "4",
"b": "2",
"c": "6"
},
{
"a": "7",
"b": "8",
"c": "9"
},
{
"a": "10",
"b": "11",
"c": "12"
},
{
"a": "13",
"b": "8",
"c": "15"
}
]
我的目标是提取此列表中键“b”具有相同“值”的所有字典。 在我的示例中它将是:
list_duplicates = [
{
"a": "1",
"b": "2",
"c": "3"
},
{
"a": "4",
"b": "2",
"c": "6"
},
{
"a": "7",
"b": "8",
"c": "9"
},
{
"a": "13",
"b": "8",
"c": "15"
}
]
我该如何执行此操作? 也许我可以使用反向逻辑:删除列表中“b”键不重复的所有字典?
查找重复项的一种非常标准的方法是使用 Counter
(您可以使用普通的字典和循环,但 Counter
使它更容易),然后使用 Counter
过滤项目计数大于 1。
>>> my_list = [
... {
... "a": "1",
... "b": "2",
... "c": "3"
... },
... {
... "a": "4",
... "b": "2",
... "c": "6"
... },
... {
... "a": "7",
... "b": "8",
... "c": "9"
... },
... {
... "a": "10",
... "b": "11",
... "c": "12"
... },
... {
... "a": "13",
... "b": "8",
... "c": "15"
... }
... ]
>>> from collections import Counter
>>> b_counts = Counter(d["b"] for d in my_list)
>>> list_duplicates = [d for d in my_list if b_counts[d["b"]] > 1]
>>> list_duplicates
[{'a': '1', 'b': '2', 'c': '3'}, {'a': '4', 'b': '2', 'c': '6'}, {'a': '7', 'b': '8', 'c': '9'}, {'a': '13', 'b': '8', 'c': '15'}]
这是使用 itertools.groupby
、itertools.chain
和 filter
的功能版本:
from itertools import groupby, chain
list(chain(*filter(lambda x: len(x)>1,
(list(g) for k,g in groupby(sorted(lst, key=lambda d: d['b']),
key=lambda d: d['b']))
)))
解释:groupby
'b' 的值(为此字典必须按此键排序),然后 filter
每个大小的组,最后 chain
输出形成一个列表。
注意。我将列表命名为 lst,以免与 list
内置
输出:
[{'a': '1', 'b': '2', 'c': '3'},
{'a': '4', 'b': '2', 'c': '6'},
{'a': '7', 'b': '8', 'c': '9'},
{'a': '13', 'b': '8', 'c': '15'}]
这种方法基本上创建了一个散列图,提供了索引列表,其中存在不同的键值。这里的关键是lst
中'b'对应的值。
所以基本上 countMap
看起来像这样:
{'2': [0, 1], '8': [2, 4], '11': [3]}
据此,我们可以创建输出列表,它仅附加原始列表中键值重复的索引。
countMap = {}
for i in range(len(lst)):
val = lst[i]['b']
if countMap.get(val) is not None:
countMap[val].append(i)
else:
countMap[val] = [i]
output = []
for i in countMap.keys():
if len(countMap[i]) > 1:
for j in countMap[i]:
output.append(lst[j])
print(output)
输出
[{'a': '1', 'b': '2', 'c': '3'}, {'a': '4', 'b': '2', 'c': '6'}, {'a': '7', 'b': '8', 'c': '9'}, {'a': '13', 'b': '8', 'c': '15'}]
有列表理解:
>>> [d for d in lst if len([di for di in lst if di["b"]==d["b"]])>1]
[{'a': '1', 'b': '2', 'c': '3'},
{'a': '4', 'b': '2', 'c': '6'},
{'a': '7', 'b': '8', 'c': '9'},
{'a': '13', 'b': '8', 'c': '15'}]