2011-04-11 33 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