2016-11-11 247 views
4

創建列表我這樣定義的一個字典(名單是一個整數列表):通過遍歷字典

​​

現在,我想通過遍歷該字典創建一個新的列表。最後,我希望它看起來像這樣:

my_list = [list_name_list_item1, list_name_list_item2, 
       list_name_list_item3, another_list_name_another_list_item1] 

依此類推。

所以我的問題是:我怎麼能意識到這一點?

我試圖

for key in my_dictionary.keys(): 
    k = my_dictionary[key] 
    for value in my_dictionary.values(): 
     v = my_dictionary[value] 
     v = str(v) 
     my_list.append(k + '_' + v) 

但是,而不是所希望的輸出I接收類型錯誤(unhashable類型: '列表')在本實施例中的第4行。

回答

5

您試圖通過它的值獲取字典項目,而您已經擁有了自己的價值。

my_dictionary = {'list_name' : [1,4,5], 'another_list_name': [6,7,8]} 

my_list = [k+"_"+str(v) for k,lv in my_dictionary.items() for v in lv] 

print(my_list) 

結果:

['another_list_name_6', 'another_list_name_7', 'another_list_name_8', 'list_name_1', 'list_name_4', 'list_name_5'] 

注意,因爲在你的字典順序不能保證,列表的順序並不

使用列表理解這樣做在一個線無論是。你可以根據鍵通過排序的項目固定的順序:

my_list = [k+"_"+str(v) for k,lv in sorted(my_dictionary.items()) for v in lv] 
+0

非常感謝你的幫助!我對Python很新,所以我很感謝你的解釋和解決方案! :) – Hisushi

0

你已經寫在鍵的外環,然後用值的內環,並試圖利用各值作爲密鑰,這是在該程序失敗。只需使用字典的items方法循環鍵,值對,而不是:

["{}_{}".format(k,v) for k,v in d.items()] 

哎呀,無法解析所需的格式;我們要在內部列表中生成每個項目。不用擔心...

d={1:[1,2,3],2:[4,5,6]} 
list(itertools.chain(*(
     ["{}_{}".format(k,i) for i in l] 
     for (k,l) in d.items()))) 

這有點複雜。我們再次從字典中獲取鍵值對,然後在列表中創建一個內部循環,並將它們格式化爲字符串。這會產生內部序列,所以我們使用鏈和*將其平坦化,最後將結果保存爲一個列表。

編輯:結果Python 3.4.3在嵌套爲生成器表達式時變得相當困惑;我不得不將內部變成一個列表,或者在格式化之前替換一些k和l的組合。

再次編輯:由於有人張貼在自刪除的答案(這讓我感到困惑),所以我太過於複雜。你可以在鏈式理解中做扁平化嵌套:

["{}_{}".format(k,v) for k,l in d.items() for v in l] 

該方法也由Jean-FrançoisFabre發佈。

2

試試這個:

my_list = [] 
for key in my_dictionary: 
    for item in my_dictionary[key]: 
     my_list.append(str(key) + '_' + str(item)) 

希望這有助於。

0

你的直接問題是,dict().values()是一個生成器產生的字典值,而不是關鍵字,所以當你嘗試在第4行進行查找時,它會失敗(在這種情況下),因爲字典中的值可以不能用作鑰匙。在另一種情況下,比如{1:2, 3:4},它會失敗,並且KeyError{1:2, 2:1}不會引發錯誤,但可能會導致令人困惑的行爲。

至於您的實際問題,列表不會將任何名稱歸於數據,就像字典一樣;他們只是存儲索引。

def f() 
    a = 1 
    b = 2 
    c = 3 
    l = [a, b, c] 

    return l 

調用f()將返回[1, 2, 3],與ab任何概念,c被完全喪失。

如果你想只是在連接列表中你的字典,使得第一副本,然後調用.extend()上就足夠了:

my_list = my_dictionary['list_name'][:] 
my_list.extend(my_dictionary['another_list_name']) 

如果你正在尋找保持列表的順序'項目,同時仍然提到他們的名字,看看OrderedDict class in collections

+0

這不是值()是一個發電機;它的價值不是關鍵。在他的情況下,他們是列表,這是不可哈希,因此*不能*鍵,所以他得到一個類型錯誤,而不是一個關鍵錯誤。 –

+0

我措辭不佳;它應該說「是」而不是「回報」。 –

0

使用列表理解這樣

d = {"test1":[1,2,3,],"test2":[4,5,6],"test3":[7,8,9]} 

new_list = [str(item[0])+'_'+str(v) for item in d.items() for v in item[1]] 

輸出:

new_list: 
['test1_1', 
'test1_2', 
'test1_3', 
'test3_7', 
'test3_8', 
'test3_9', 
'test2_4', 
'test2_5', 
'test2_6'] 
0

讓我們初始化我們的數據

In [1]: l0 = [1, 2, 3, 4] 

In [2]: l1 = [10, 20, 30, 40] 

In [3]: d = {'name0': l0, 'name1': l1} 

注意,在我的例子,從你的不同,名單內容不是字符串...不是列出異構容器嗎?

也就是說,您不能簡單地加入鍵和列表項,您最好使用內建的str(...)將這些值轉換爲字符串。

現在來解決你的問題......我用一個列表理解 與兩個循環,外部循環首先,它是在字典中的項目(即鍵值對夫婦),內部循環次之,它在相應列表中的項目上。

In [4]: res = ['_'.join((str(k), str(i))) for k, l in d.items() for i in l] 

In [5]: print(res) 
['name0_1', 'name0_2', 'name0_3', 'name0_4', 'name1_10', 'name1_20', 'name1_30', 'name1_40'] 

In [6]: 

在你的情況下,使用str(k)+'_'+str(i)將被罰款爲好,但對於具有固定'text'連接字符串當前成語是'text'.join(...)方法。請注意,.join需要一個SINGLE參數,一個可迭代的,因此在列表理解中,我使用join((..., ...)) 來收集單個參數中的聯合。

+0

post scriptum - 正如其他人在他們的回答中所說的那樣,你無法保證在外部循環中檢索到的'k,l'項的任何特定順序。 – gboffi