簡體   English   中英

在Python字典中遍歷值列表

[英]iterating over values list in Python dictionary

嗨,我想遍歷每個關鍵字都有值列表的Python字典,我想創建一個新的列表/字典來分隔每個值[x]或直接用分隔的值做事。

這是我擁有的字典的簡化示例:

all_parameters = {"first": ["1a","1b","1c"], "second": ["2a","2b","2c"], "third": ["3a","3b","3c"]}

我正在尋找這樣的值分開(通過創建一個新的字典或列表或直接用分開的值做事)。

grouped_parameters = [{"first": "1a", "second": "2a", "third": "3a"},
                      {"first": "1b", "second": "2b", "third": "3b"},
                      {"first": "1c", "second": "2c", "third": "3c"}]

我確保如何正確迭代每個key:value對。

i = 0
for k, v in all_parameters.items():
    for item in v:
        # stuck here
    i+=1

最終,我要執行的“工作”是將每個輸出(例如,“ {{first”:“ 1a”,“ second”:“ 2a”,“ third”:“ 3a”}')轉換為字符串,這樣我可以將每個參數組發布到表中的單元格,因此理想情況下,我寧願動態地執行此操作,而不是創建新的字典。

任何幫助將不勝感激。

假設所有列表的長度相同:

>>> length = len(next(all_parameters.itervalues()))
>>> [{k:v[i] for k,v in all_parameters.iteritems()} for i in range(length)]
[{'second': '2a', 'third': '3a', 'first': '1a'}, {'second': '2b', 'third': '3b', 'first': '1b'}, {'second': '2c', 'third': '3c', 'first': '1c'}]

在Python 3中,使用len(next(iter(all_parameters.values())))items而不是iteritems

(完成迭代器的惡作劇是因為如果只需要任意值列表的長度,則不需要所有字典值的列表。)

普通字典中的項目沒有排序*,因此,如果要將字段轉換為特定順序,則在將字典轉換為字符串時需要格外小心。

此代碼使用一個元組,其中包含我們希望它們在輸出dict字符串中出現的順序的鍵字符串。

all_parameters = {
    "first": ["1a","1b","1c"], 
    "second": ["2a","2b","2c"], 
    "third": ["3a","3b","3c"],
}

# We want keys to be in this order
all_keys = ("first", "second", "third")

# Assumes all value lists are the same length.
for t in zip(*(all_parameters[k] for k in all_keys)):
    a = ['"{}": "{}"'.format(u, v) for u, v in zip(all_keys, t)]
    print('{' + ', '.join(a) + '}')

產量

{"first": "1a", "second": "2a", "third": "3a"}
{"first": "1b", "second": "2b", "third": "3b"}
{"first": "1c", "second": "2c", "third": "3c"}

這個怎么運作

我們首先使用生成器表達式(all_parameters[k] for k in all_keys) ,該表達式按all_keys指定的順序從all_parameters中生成值列表。 我們使用* “ splat”運算符將這些列表作為args傳遞給zip 因此,對於您的示例數據,它相當於像這樣調用zip

zip(["1a","1b","1c"], ["2a","2b","2c"], ["3a","3b","3c"])

zip有效地轉換了傳遞給它的可迭代對象,因此該調用的結果是生成這些元組的迭代器:

('1a', '2a', '3a'), ('1b', '2b', '3b'), ('1c', '2c', '3c')

然后我們用for t in zip(...)for t in zip(...)逐個循環這些元組,因此在第一個循環中t獲得值('1a', '2a', '3a') ,然后是('1b', '2b', '3b')等。

接下來,我們有一個列表推導,它將值字符串和相應的鍵字符串壓縮在一起,並將它們格式化為在每個鍵和值字符串周圍用雙引號引起來的字符串。 然后,我們將這些字符串與逗號和空格作為分隔符連接在一起(並添加大括號字符)以構成最終的dict字符串。


*實際上,在Python 3.6中,普通字典確實會保留插入順序,但這是當前的實現細節,因此不應依賴它。

如果列表的長度可能不同,則可以將mapNone一起使用,如下所示:

all_parameters = {"first": ["1a", "1b", "1c", "1d"], "second": ["2a", "2b", "2c"], "third": ["3a", "3b", "3c"]}

final = [dict(zip(all_parameters.keys(), values)) for values in map(None, *all_parameters.values())]

print final

map(None, *all_parameters.values())為您提供每個索引處每個鍵的值的元組-例如('1a', '2a', '3a') ,並將其壓縮到鍵上並創建一個字典,我們得到所需的組合。

注意:這僅適用於Python 2.x,因為在3.x中更改了map 對於Python 3.x,我們可以使用itertools.zip_longest

from itertools import zip_longest

all_parameters = {"first": ["1a", "1b", "1c", "1d"], "second": ["2a", "2b", "2c"], "third": ["3a", "3b", "3c"]}

final = [dict(zip(all_parameters.keys(), values)) for values in zip_longest(*all_parameters.values())]

print(final)

在這兩種情況下,我們得到:

[{'second': '2a', 'third': '3a', 'first': '1a'}, {'second': '2b', 'third': '3b', 'first': '1b'}, {'second': '2c', 'third': '3c', 'first': '1c'}, {'second': None, 'third': None, 'first': '1d'}]

我不確定這是否是您想要的

for i in range(len(all_parameters['first'])):
     for position in all_parameters:
         print(position+" "+all_parameters[position][i])

給出這樣的輸出

第一1a第二2a第三3a第一1b第二2b第三3b第一1c第二2c第三3c

僅當每個字典元素的列表大小與第一個列表大小相同時,此方法才有效。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM