2011-06-25 100 views
2

在Python中,我有一個字典列表:在詞典列表中,基於一個鍵/值匹配字典嗎?

mylist = [ { 'name': 'James', 'school': 'UCLA', 'date_joined': 2001 }, 
      { 'name': 'Jack', 'school': 'UCLA', 'date_joined': 2001 }, 
      { 'name': 'Fisher', 'school': 'NYU', 'date_joined': 2003 }] 

如何檢查有一定的字典是否匹配現有記錄,只根據姓名和學校的鍵/值

所以:

example1 = { 'name': 'James', 'school': 'UCLA', 'date_joined': 2007 } 
example1 = { 'name': 'James', 'school': 'UCLA', 'date_joined': 2001 } 

應該都匹配,但

example3 = { 'name': 'James', 'school': 'MIT', date_joined': 2001 } 

不應該。

有明顯:

for m in myList: 
    if (m['name']==example['name'] and m['school']==example['school']): 
     match_found = True 
     continue 

但有一個更緊湊的方式?

+0

,但你可能會考慮使用[不同數據結構](http://stackoverflow.com/questions/6479377/in-list-of-dicts-match-dict-based-on-one-key-value/6479532#6479532)。 – senderle

回答

4
fields = ('name', 'school') 
match_found = any(all(x[f]==example[f] for f in fields) for x in myList) 
2
if all(m[k]==example[k] for k in ('school','name')) 
2

不知道任何有關你的程序的結構,我的做法可能會有所不同:

from collections import namedtuple 
import datetime 

StudentRecord = namedtuple('StudentRecord', 'name school date_joined') 
myset = set([StudentRecord('James', 'UCLA', 2001), 
      StudentRecord('Jack', 'UCLA', 2001), 
      StudentRecord('Fisher', 'NYU', 2003)]) 
this_year = datetime.datetime.today().year 
match_found = any(StudentRecord('James', 'UCLA', year) in myset for year in range(1950, this_year)) 

這將是非常小的錶慢,因爲它必須檢查每年,但對於成千上萬的學生名單,其中沒有一個在1950年以前進入學校,這將會快得多。這是多少年的O(n),而列表方法是O(n)的學生人數,年數可能會比學生人數增長得慢得多。 (它要求沒有記錄是相同的,雖然 - 但是,你可能想的是反正或者,你總是可以使用列表的字典,而不是一組來處理衝突。)

而且,對於一個真正的常數時間的算法可以做到這一點,利用多年的多個相同的學生列表,列表,這也解決衝突的問題:即將有點晚與這個遊戲

StudentRecord = namedtuple('StudentRecord', 'name school') 
mydict = {StudentRecord('James', 'UCLA'):[2001], 
      StudentRecord('Jack', 'UCLA') :[2001], 
      StudentRecord('Fisher', 'NYU'):[2003, 2007]} 
match_found = StudentRecord('James', 'UCLA') in mydict 
+0

+1更好的數據結構FTW。雖然除非這是整個示例,我猜測內存中的'sqlite'數據庫實際上可能會更好。 – katrielalex

相關問題