2016-02-12 155 views
0

內部列表可以說我有這樣的詞典:遍歷嵌套的字典

myDict = { 
    1: { 
     "a": "something", 
     "b": [0, 1, 2], 
     "c": ["a", "b", "c"] 
    }, 
    2: { 
     "a": "somethingElse", 
     "b": [3, 4, 5], 
     "c": ["d", "e", "f"] 
    }, 
    3: { 
     "a": "another", 
     "b": [6, 7, 8], 
     "c": ["g", "h", "i"] 
    } 
} 

這是我的代碼:

for id, obj in myDict.items(): 
    for key, val in obj.items(): 
     if key is "b": 
      for item in val: 
       # apply some function to item 

有沒有更好的方式來遍歷一個列表內嵌字典?或者有沒有pythonic的方式來做到這一點?

+0

'如果key爲 「B」',但怎麼樣' 「C」'?他們也是名單。你不想要他們? – gil

+0

@gill我不需要「c」。我只需要「b」中的值,因爲我需要爲列表中的每個值應用一些函數。 – Mico

回答

1

如果你的字典總是兩層深,我沒有看到你的方法有什麼問題。在你的實現中,我將使用key == "b"而不是key is "b"。使用is將測試身份(例如id(a) == id(b)),而==將測試是否相等(例如a.__eq__(b))。當我在IDLE中測試它時,它的功能是一樣的,但這不是一個好習慣。這裏有一個關於它的詳細信息:How is the 'is' keyword implemented in Python?

如果你要處理的不同級別的字典,你可以使用類似:

def test_dict_for_key(dictionary, key, function): 
    for test_key, value in dictionary.items(): 
     if key == test_key: 
      dictionary[key] = type(value)(map(function, value)) 
     if isinstance(value, dict): 
      test_dict_for_key(value, key, function) 

使用示例可能是這樣的:

myDict = { 
    1: { 
     "a": "something", 
     "b": [0, 1, 2], 
     "c": ["a", "b", "c"] 
    }, 
    2: { 
     "a": "somethingElse", 
     "b": [3, 4, 5], 
     "c": ["d", "e", "f"] 
    }, 
    3: { 
     "a": "another", 
     "b": [6, 7, 8], 
     "c": ["g", "h", "i"] 
    } 
} 

# adds 1 to every entry in each b 
test_dict_for_key(myDict, "b", lambda x: x + 1) 

# prints [1, 2, 3] 
print(myDict[1]["b"]) 
+0

很多答案我的所有問題,謝謝! – Mico

0

可以進行一些修復。

  1. 不要比較兩個字符串(if key is "b":
  2. 當簡單的說print(item)而是採用.format()使用is,因爲你只有那你打印一個變量,沒有額外的字符串格式化

修改後的代碼:

for id, obj in myDict.items(): 
    for key, val in obj.items(): 
     if key == "b": 
      for item in val: 
       print(item) 
2

你絕對不需要迭代列表來打印它(除非這是您正在編寫的代碼的功能要求)。

很簡單,你可以這樣做:

for id, obj in myDict.items(): 
    if "b" in obj: 
     print obj["b"] 

要映射列表對象,通過obj['b']爲代表的其他功能,您可以使用map功能:

map(foo, obj["b"]) 
+0

我不想只打印它。我需要爲列表中的每個值應用一些函數。 – Mico

+0

好的,那麼在我的回答中你可以做'map(foo,obj ['b'])'而不是'print'。 –

+0

如果我使用地圖,它會更新列表嗎? – Mico

0

如果確定你會在每種情況下都有一個b密鑰,你可以簡單地做:

for id, obj in myDict.items(): 
    for item in obj["b"]: 
     print item 
1

我是發電機表達式的粉絲。

inner_lists = (inner_dict['b'] for inner_dict in myDict.values()) 
# if 'b' is not guaranteed to exist, 
# replace inner_dict['b'] with inner_dict.get('b', []) 
items = (item for ls in inner_lists for item in ls) 

現在你可以使用一個foo循環

for item in items: 
    # apply function 

map

transformed_items = map(func, items)