我有一个未知数量的产品结果列表作为字典条目,它们都具有相同的键。我想生成一个出现在所有旧列表中的新产品列表。
'所有城市都有哪些产品?'
下式给出:
list1 = [{'id': 1, 'name': 'bat', 'price': 20.00}, {'id': 2, 'name': 'ball', 'price': 12.00}, {'id': 3, 'name': 'brick', 'price': 19.00}]
list2 = [{'id': 1, 'name': 'bat', 'price': 18.00}, {'id': 3, 'name': 'brick', 'price': 11.00}, {'id': 2, 'name': 'ball', 'price': 17.00}]
list3 = [{'id': 1, 'name': 'bat', 'price': 16.00}, {'id': 4, 'name': 'boat', 'price': 10.00}, {'id': 3, 'name': 'brick', 'price': 15.00}]
list4 = [{'id': 1, 'name': 'bat', 'price': 14.00}, {'id': 2, 'name': 'ball', 'price': 9.00}, {'id': 3, 'name': 'brick', 'price': 13.00}]
list...
我想要一个dicts列表,其中'id'存在于所有旧列表中:
result_list = [{'id': 1, 'name': 'bat}, {'id': 3, 'name': 'brick}]
对于给定的“id”不是常量的值可以被丢弃,但是给定“id”的值必须在结果列表中。
如果我知道我有多少名单,我可以这样做:
results_list = []
for dict in list1:
if any(dict['id'] == d['id'] for d in list2):
if any(dict['id'] == d['id'] for d in list3):
if any(dict['id'] == d['id'] for d in list4):
results_list.append(dict)
如果我不知道我有多少个名单,怎么能这样做呢?
答案 0 :(得分:5)
将id
放入set
s,然后取set
s的交叉点。
list1 = [{'id': 1, 'name': 'steve'}, {'id': 2, 'name': 'john'}, {'id': 3, 'name': 'mary'}]
list2 = [{'id': 1, 'name': 'jake'}, {'id': 3, 'name': 'tara'}, {'id': 2, 'name': 'bill'}]
list3 = [{'id': 1, 'name': 'peter'}, {'id': 4, 'name': 'rick'}, {'id': 3, 'name': 'marci'}]
list4 = [{'id': 1, 'name': 'susan'}, {'id': 2, 'name': 'evan'}, {'id': 3, 'name': 'tom'}]
lists = [list1, list2, list3, list4]
sets = [set(x['id'] for x in lst) for lst in lists]
intersection = set.intersection(*sets)
print(intersection)
结果:
{1, 3}
请注意,我们调用类方法set.intersection
而不是实例方法set().intersection
,因为后者将其参数与空集set()
交叉,当然还有任何空集都是空的。
如果你想把它变成一个dicts列表,你可以这样做:
result = [{'id': i, 'name': None} for i in intersection]
print(result)
结果:
[{'id': 1, 'name': None}, {'id': 3, 'name': None}]
现在,如果您还想保留对于给定id
的所有实例都相同的属性,您将要执行以下操作:
list1 = [{'id': 1, 'name': 'bat', 'price': 20.00}, {'id': 2, 'name': 'ball', 'price': 12.00}, {'id': 3, 'name': 'brick', 'price': 19.00}]
list2 = [{'id': 1, 'name': 'bat', 'price': 18.00}, {'id': 3, 'name': 'brick', 'price': 11.00}, {'id': 2, 'name': 'ball', 'price': 17.00}]
list3 = [{'id': 1, 'name': 'bat', 'price': 16.00}, {'id': 4, 'name': 'boat', 'price': 10.00}, {'id': 3, 'name': 'brick', 'price': 15.00}]
list4 = [{'id': 1, 'name': 'bat', 'price': 14.00}, {'id': 2, 'name': 'ball', 'price': 9.00}, {'id': 3, 'name': 'brick', 'price': 13.00}]
lists = [list1, list2, list3, list4]
sets = [set(x['id'] for x in lst) for lst in lists]
intersection = set.intersection(*sets)
all_keys = set(lists[0][0].keys())
result = []
for ident in intersection:
res = [dic for lst in lists
for dic in lst
if dic['id'] == ident]
replicated_keys = []
for key in all_keys:
if len(set(dic[key] for dic in res)) == 1:
replicated_keys.append(key)
result.append({key: res[0][key] for key in replicated_keys})
print(result)
结果:
[{'id': 1, 'name': 'bat'}, {'id': 3, 'name': 'brick'}]
我们在这里做的是:
id
中的每个intersection
并抓住与id
对应的每个字典。id
)。result
此代码假定:
list1, list2, ...
中的每个字典都有相同的键。如果这个假设是错误的,请告诉我 - 它不应该让人放松。