2017-08-04 55 views
0

我正在嘗試創建字典中所有第n級元素的列表。獲取字典中所有第n級元素

我寧願解決方案是通用的第n項,雖然我的例子下面列出了兩個級別。

如果你想象中的問題,如下圖:

enter image description here

我試圖從16-31獲得所有值的列表。

例如, 我有一個i字典ij水龍頭,我需要找出是否有任何水龍頭上。

有沒有一種方法來創建爲我所有的抽頭輸出的列表只是通過使用搜索:

for i in list_of_tap_outputs: 
    new_list+=lambda x:x[2] 

或別的東西,還是我對自己辭職使用名單。我還希望能夠跟蹤整個系統中的哪個水龍頭。如果我使用列表,我必須記住哪個水龍頭分配了列表中的哪個索引,並且不想這樣做。

data={'House'+str(i): {"Tap"+str(j): 'on' if random.randint(1,2)%2==1 else 'off' 
         for j in range(4)} for i in range(3)} 

print data 

與輸出這樣的:

{'House2': {'Tap1': 'off', 'Tap0': 'on', 'Tap3': 'off', 'Tap2': 'off'}, 
'House0': {'Tap1': 'off', 'Tap0': 'on', 'Tap3': 'on', 'Tap2': 'on'}, 
'House1': {'Tap1': 'off', 'Tap0': 'on', 'Tap3': 'off', 'Tap2': 'on'}} 
+0

將數據是什麼樣子了兩個多層次的輸入字典?也請更詳細地描述你想要的輸出格式。 – martineau

+0

我添加的圖像有幫助嗎? – azazelspeaks

+0

我不確定。中間級別的密鑰會是什麼樣子(儘管我不確定它很重要)?我想要一些包含2個以上級別的示例數據來測試代碼,以便改進我現有的答案。 – martineau

回答

2
def any_tap_on(data): 
    for house, taps in data.items(): 
     for tap, status in taps.items(): 
      if status == 'on': 
       return True 
    return False 

或者,它可以更快地使用in關鍵字 - 儘可能複雜的順序,這是一樣的,但內置操作往往跑得更快:針對任何自來水

def any_tap_on(data): 
    for house, taps in data.items(): 
     if 'on' in taps.values(): 
      return True 
    return False 
+2

你正在尋找M個房屋中的N個水龍頭中的一個,所以你不能做任何比O(NxM)更好的事情。 – bfontaine

+0

您可以將字典更改爲'{'on':{'house1':['t1'...],...},'off':{'house1':['t2'...], ...}以加快檢查任何正在進行的檢查,但這可能會減慢其他地方的速度 – dashiell

+0

是否有更通用的解決方案用於第n個項目? – azazelspeaks

2

檢查:

any('on' in taps.values() for taps in data.values()) 

檢查特定水龍頭上任何房屋:

any(taps['Tap0'] == 'on' for taps in data.values()) 

您可以使用all()檢查所有的水龍頭上爲好。

+0

嗯,我沒有意識到任何(),但這肯定會比我的回答 – TallChuck

0

我不知道兩個以上的「級別」會是什麼樣子,但它是爲他們的1很簡單:

from pprint import pprint 
import random 

data={'House'+str(i): {"Tap"+str(j): 'on' if random.randint(1,2)%2==1 else 'off' 
         for j in range(4)} for i in range(3)} 

def get_nth_level_elements(d): 
    results = [] 
    for key, value in d.items(): 
     results.append(value) 
    return results 

results = get_nth_level_elements(data) 
pprint(results) 

輸出:

[{'Tap0': 'on', 'Tap1': 'off', 'Tap2': 'on', 'Tap3': 'off'}, 
{'Tap0': 'on', 'Tap1': 'off', 'Tap2': 'on', 'Tap3': 'off'}, 
{'Tap0': 'on', 'Tap1': 'on', 'Tap2': 'off', 'Tap3': 'on'}] 
0

所以,你似乎在這裏問兩個問題,而不是集中在房子和水龍頭的用例上,在這個答案中,我會嘗試解決一般情況。我不熟悉Python的實現細節,也不熟悉所有的內置函數和標準庫,但我認爲生成像你這樣的列表的唯一可行的方法是使用遞歸功能。你似乎正在像搜索樹一樣查看這個問題,如果你足夠關注它,你可以找到很多關於這些問題的解讀。

下面是一個應該完成這項工作的示例函數。我沒有廣泛測試,但它至少適用於您提供的示例數據。

def extract_nth_level(root, n): 
    if n == 0: 
     return [root] 
    values = [] 
    if isinstance(root, dict): 
     for subtree in root.values(): 
      values += extract_nth_level(subtree, n-1) 
    return values 

data = { 
    'House2': {'Tap1': 'off', 'Tap0': 'on', 'Tap3': 'off', 'Tap2': 'off'}, 
    'House0': {'Tap1': 'off', 'Tap0': 'on', 'Tap3': 'on', 'Tap2': 'on'}, 
    'House1': {'Tap1': 'off', 'Tap0': 'on', 'Tap3': 'off', 'Tap2': 'on'} 
} 

print extract_nth_level(data, 2) 

這將打印以下列表:

['off', 'on', 'off', 'off', 'off', 'on', 'on', 'on', 'off', 'on', 'off', 'on']