在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 :(得分: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'))