在dicts列表中,根据一个键/值匹配dict?

时间:2011-06-25 17:27:16

标签: python

在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

但是有更紧凑的方式吗?

3 个答案:

答案 0 :(得分:4)

fields = ('name', 'school')
match_found = any(all(x[f]==example[f] for f in fields) for x in myList)

答案 1 :(得分:3)

对程序结构一无所知,我的方法可能会有所不同:

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

答案 2 :(得分:2)

if all(m[k]==example[k] for k in ('school','name'))