2014-01-17 29 views
1

我有一個未知數量的產品結果列表作爲字典條目,它們都具有相同的密鑰。我想要生成出現在所有舊列表中的新產品列表。在n個列表中創建一個共同的字典列表?

'所有城市都有哪些產品?'

給出:

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... 

我想類型的字典列表中的「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

我已更新我的解決方案以符合您更新的問題。 – senshin

回答

5

id s寫入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(),當然交集任何有空集的東西都是空的。

如果你想要把這個回類型的字典列表,你可以這樣做:

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'}] 

我們在這裏做的是:

  • 看在intersection每個id搶對應於每個id字典。
  • 查找哪些鍵在所有這些字符中具有相同的值(其中之一保證爲id)。
  • 將這些鍵值對到result

此代碼假定:

  • list1, list2, ...每字典將具有相同的密鑰。如果這個假設是錯誤的,請告訴我 - 不應該很難放鬆。
+0

如果我不知道有多少個名單,我該怎麼辦?我如何構建這個? '列表= [列表1,list2中,項目list3,list4,...]' 此外,如果我有在http://stardict.sourceforge.net/Dictionaries.php下載幾個鍵/值對(其是對於給定的ID常數)...如何我可以用原始字典的所有值構建結果列表嗎?我需要在舊列表中查找交叉點中的k/v對以構建結果嗎? – user3205089

+0

@ user3205089你的列表來自哪裏?如果你不知道它們有多少,那麼肯定它們必須放在一些容器數據結構中。對於您剛剛提出的其他問題,請更詳細地更新您的問題,並提供更多關於您的數據的更多信息。 – senshin

+0

不同城市的產品結果的實際列表。我可能有1個,我有7個結果列表。我想創建出現在所有城市的產品列表。 product_id和name將是不變的,merchant_id和價格可能不是。我意識到這是一個更清晰的例子,我會更新我最初的問題。 – user3205089