2011-04-11 34 views
2

我想交叉引用字典和django查询集,以确定哪些元素分别具有唯一的dictionary['name']djangoModel.name值。我现在做这个的方法是:Pythonic方法来解析特定属性的字典列表?

  • 创建词典列表[“名”]值
  • 创建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] 

感觉unpythonic不得不根创建中间名称列表(上面的第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

你介意提供一些示例数据?这将使问题更容易可视化。但是,如果您只是在两个不同的名称列表中寻找唯一的成员,那么不需要深入研究它,这似乎是比较两个set()容器的最佳位置。 – jathanism 2011-04-11 15:44:27

回答

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())] 

obsoleteTests = list(set([a.name for a in alldbTests]) - set(vctestNames)) 

设置比较对象的两个列表(pseudopython)时是非常有用的

+1

正确的是'set',用小写“s” – jsbueno 2011-04-11 15:50:25

+0

修正,谢谢。 – manji 2011-04-11 15:51:31

+0

虽然这些将会是一组字符串。我同意我想使用集合,但我认为我真正的问题是“如何在使用完整字典(或django模型)对象时使用集合提供的功能?” – Nathan 2011-04-11 15:52:47

2

您正在使用基本设置操作。您可以将您的对象转换为集和刚刚找到交叉点(认为维恩图):

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] 
+0

但是,obsoleteTests是一个名称列表,而不是来自数据库的模型 - 我需要完整的模型。 – Nathan 2011-04-11 15:50:33

+0

帮你Django。你为什么这么做很难?!?!? – Blender 2011-04-11 15:51:42

+0

看到 - 就是这样。我有两种不同类型的对象 - 字典和django模型。比较它们的唯一方法是通过它们的名称属性,每个属性都不相同。 – Nathan 2011-04-11 15:57:30