Reputation: 71
This is a question about Python. I have the following list of dictionaries:
listA = [
{"t": 1, "tid": 2, "gtm": 3, "c1": 4, "id": "111"},
{"t": 3, "tid": 4, "gtm": 3, "c1": 4, "c2": 5, "id": "222"},
{"t": 1, "tid": 2, "gtm": 3, "c1": 4, "c2": 5, "id": "333"},
{"t": 5, "tid": 6, "gtm": 3, "c1": 4, "c2": 5, "id": "444"}
]
and a dictionary I wanted to compare with:
dictA = {"t": 1, "tid": 2, "gtm": 3}
I wanted to create a list of dicts that match all the items in dictA from listA and to include the "id" field as well:
listB = [
{"t": 1, "tid": 2, "gtm": 3, "id": "111"},
{"t": 1, "tid": 2, "gtm": 3, "id": "333"}
]
I tried doing this:
for k in listA:
for key, value in k.viewitems() & dictA.viewitems():
print key, value
But it's matching any item in dictA.
Upvotes: 3
Views: 673
Reputation: 180391
You would need to check the length of the intersection, just checking if dct.viewitems() & dictA.viewitems()
would evaluate to True for any intersection :
[dct for dct in listA if len(dct.viewitems() & dictA.viewitems()) == len(dictA)]
Or just check for a subset, if the items from dictA are a subset of each dict:
[dct for dct in listA if dictA.viewitems() <= dct.viewitems()]
Or reverse the logic looking for a superset:
[dct for dct in listA if dct.viewitems() >= dictA.viewitems()]
Upvotes: 3
Reputation: 16081
Try this,all
will check the existence of dictA
in listA
.
[i for i in listA if all(j in i.items() for j in dictA.items())]
Result
[{'c1': 4, 'gtm': 3, 'id': '111', 't': 1, 'tid': 2},
{'c1': 4, 'c2': 5, 'gtm': 3, 'id': '333', 't': 1, 'tid': 2}]
Upvotes: 1
Reputation: 1485
For python 2.7 :
listA = [
{"t": 1, "tid": 2, "gtm": 3, "c1": 4, "id": "111"},
{"t": 3, "tid": 4, "gtm": 3, "c1": 4, "c2": 5, "id": "222"},
{"t": 1, "tid": 2, "gtm": 3, "c1": 4, "c2": 5, "id": "333"},
{"t": 5, "tid": 6, "gtm": 3, "c1": 4, "c2": 5, "id": "444"}
]
dictA = {"t": 1, "tid": 2, "gtm": 3}
for k in listA:
if all(x in k.viewitems() for x in dictA.viewitems()):
print k
It gives output as :
{'tid': 2, 'c1': 4, 'id': '111', 't': 1, 'gtm': 3}
{'gtm': 3, 't': 1, 'tid': 2, 'c2': 5, 'c1': 4, 'id': '333'}
And if you want to create list then instead of print
, add dictionary to list As follows:
listA = [
{"t": 1, "tid": 2, "gtm": 3, "c1": 4, "id": "111"},
{"t": 3, "tid": 4, "gtm": 3, "c1": 4, "c2": 5, "id": "222"},
{"t": 1, "tid": 2, "gtm": 3, "c1": 4, "c2": 5, "id": "333"},
{"t": 5, "tid": 6, "gtm": 3, "c1": 4, "c2": 5, "id": "444"}
]
dictA = {"t": 1, "tid": 2, "gtm": 3}
ans =[]
for k in listA:
if all(x in k.viewitems() for x in dictA.viewitems()):
ans.append(k)
#print k
print ans
It gives output:
[{'tid': 2, 'c1': 4, 'id': '111', 't': 1, 'gtm': 3}, {'gtm': 3, 't': 1, 'tid': 2, 'c2': 5, 'c1': 4, 'id': '333'}]
Upvotes: 1
Reputation: 2271
You can use a dictionary view:
listA = [
{"t": 1, "tid": 2, "gtm": 3, "c1": 4, "id": "111"},
{"t": 3, "tid": 4, "gtm": 3, "c1": 4, "c2": 5, "id": "222"},
{"t": 1, "tid": 2, "gtm": 3, "c1": 4, "c2": 5, "id": "333"},
{"t": 5, "tid": 6, "gtm": 3, "c1": 4, "c2": 5, "id": "444"}
]
dictA = {"t": 1, "tid": 2, "gtm": 3}
for k in listA:
if dictA.viewitems() <= k.viewitems():
print k
And for python 3 use:
if dictA.items() <= k.items():
print(k)
Upvotes: 2