我希望交叉引用字典和django查询集,以确定哪些元素分别具有唯一的dictionary['name']
和djangoModel.name
值。我现在这样做的方式是:
这看起来如下:
alldbTests = dbp.test_set.exclude(end_date__isnull=False) #django queryset
vctestNames = [vctest['name'] for vctest in vcdict['tests']] #from dictionary
dbtestNames = [dbtest.name for dbtest in alldbTests] #from django model
# Compare tests in protocol in fortytwo's db with protocol from vc
obsoleteTests = [dbtest for dbtest in alldbTests if dbtest.name not in vctestNames]
newTests = [vctest for vctest in vcdict if vctest['name'] not in dbtestNames]
必须生成名称的中间列表(上面的第2行和第3行)才能感觉到单声道,只是为了能够在之后立即检查包含。我错过了什么吗?我想我可以将两个列表推导放在一行中,如下所示:
obsoleteTests = [dbtest for dbtest in alldbTests if dbtest.name not in [vctest['name'] for vctest in vcdict['tests']]]
但这似乎更难以遵循。
修改: 想想这样的初始状态:
# vcdict is a list of django models where the following are all true
alldBTests[0].name == 'test1'
alldBTests[1].name == 'test2'
alldBTests[2].name == 'test4'
dict1 = {'name':'test1', 'status':'pass'}
dict2 = {'name':'test2', 'status':'pass'}
dict3 = {'name':'test5', 'status':'fail'}
vcdict = [dict1, dict2, dict3]
我无法转换为集合并取消差异,除非我将内容删除到只是名称字符串,但后来我无法访问模型/字典的其余部分,对吧?如果在两种情况下我都有相同类型的对象,那么集合只能在这里工作。
答案 0 :(得分:4)
vctestNames = dict((vctest['name'], vctest) for vctest in vcdict['tests'])
dbtestNames = dict((dbtest.name, dbtest) for dbtest in alldbTests)
obsoleteTests = [vctestNames[key]
for key in set(vctestNames.keys()) - set(dbtestNames.keys())]
newTests = [dbtestNames[key]
for key in set(dbtestNames.keys()) - set(vctestNames.keys())]
答案 1 :(得分:2)
您正在使用基本的设置操作。您可以将对象转换为集合并找到交集(想想维恩图):
obsoleteTests = list(set([a.name for a in alldbTests]) - set(vctestNames))
在比较两个对象列表(pseudopython)时,集合非常有用:
set(a) - set(b) = [c for c in a and not in b]
set(a) + set(b) = [c for c in a or in b]
set(a).intersection(set(b)) = [c for c in a and in b]
答案 2 :(得分:2)
intersection
的{{1}} - 和difference
- 操作可以帮助您更优雅地解决问题。
但是,由于您最初处理的是dicts,这些示例和讨论可能会提供一些启示:sets