簡體   English   中英

將帶有列表的字典轉換為字典列表

[英]Converting a dictionary with lists into a list of dictionaries

我有這本字典,其中包含列表,因為它們是鍵的值。

d = {'n': ['a', 'b', 'x'], 'a': [1, 2, 3], 'p': ['123', '321', '456']}

我想轉換成這樣的字典列表

[{'n':'a','a':1,'p':'123'},{'n':'b','a':2,'p':'321'},{ 'n':'x','a':3,'p':'456'}]

我目前的解決方案是,

the_kv = d.items()
f = {}
c = {}
e = {}

f_c_e = []
for i, j in the_kv:
    f[i] = j[0]
    c[i] = j[1]
    e[i] = j[2]

f_c_e.append(f)
f_c_e.append(c)
f_c_e.append(e)
print(f_c_e)

但我想知道是否有更有效的方法,而不是創建單獨的 dicts 然后將它們附加到列表中。

使用zip

[dict(zip(d, vals)) for vals in zip(*d.values())]

結果:

[{'n': 'a', 'a': 1, 'p': '123'}, {'n': 'b', 'a': 2, 'p': '321'}, {'n': 'x', 'a': 3, 'p': '456'}]

用:

res = [dict(v) for v in zip(*[[(key, value) for value in values] for key, values in d.items()])]
print(res)

輸出

[{'n': 'a', 'a': 1, 'p': '123'}, {'n': 'b', 'a': 2, 'p': '321'}, {'n': 'x', 'a': 3, 'p': '456'}]

一種更簡單的替代方法是:

result = [{} for _ in range(len(d))]
for key, values in d.items():
    for i, value in enumerate(values):
        result[i][key] = value

print(result)

輸出(替代)

[{'n': 'a', 'a': 1, 'p': '123'}, {'n': 'b', 'a': 2, 'p': '321'}, {'n': 'x', 'a': 3, 'p': '456'}]

好問題。 從一種數據類型到另一種數據類型的轉換在開發或競爭性編程中都是必不可少的。

它可以通過多種方法完成,我將在下面解釋我所知道的兩種方法:

方法#1 :使用列表推導我們可以使用列表推導作為單行替代來執行各種簡單的任務,提供可讀性和更簡潔的代碼。 我們可以遍歷每個字典元素並相應地繼續構造字典列表。

# Python3 code to demonstrate 
# to convert dictionary of list to 
# list of dictionaries
# using list comprehension
  
# initializing dictionary
test_dict = { "Rash" : [1, 3], "Manjeet" : [1, 4], "Akash" : [3, 4] }
  
# printing original dictionary
print ("The original dictionary is : " + str(test_dict))
  
# using list comprehension
# to convert dictionary of list to 
# list of dictionaries
res = [{key : value[i] for key, value in test_dict.items()}
         for i in range(2)]
  
# printing result
print ("The converted list of dictionaries " +  str(res))

方法#2 :使用 zip() 這種方法使用了兩次 zip 函數,第一次是我們需要將所有列表的特定索引值壓縮為一個,第二次是為了獲取特定索引的所有值並使用相應的鍵對其進行壓縮。

# Python3 code to demonstrate
# to convert dictionary of list to
# list of dictionaries
# using zip()

# initializing dictionary
test_dict = { "Rash" : [1, 3], "Manjeet" : [1, 4], "Akash" : [3, 4] }

# printing original dictionary
print ("The original dictionary is : " + str(test_dict))

# using zip()
# to convert dictionary of list to
# list of dictionaries
res = [dict(zip(test_dict, i)) for i in zip(*test_dict.values())]

# printing result
print ("The converted list of dictionaries " + str(res))

輸出

The original dictionary is : {‘Rash’: [1, 3], ‘Manjeet’: [1, 4], ‘Akash’: [3, 4]}
The converted list of dictionaries [{‘Rash’: 1, ‘Manjeet’: 1, ‘Akash’: 3}, {‘Rash’: 3, ‘Manjeet’: 4, ‘Akash’: 4}]

讓我們一步一步地解決這個問題。

核心困難在於我們有一系列列表:

['a', 'b', 'x']
[1, 2, 3]
['123', '321', '456']

並且我們想要產生由每個列表的元素 0、每個列表的元素 1 等組成的序列(這些序列中的每一個都包含輸出字典的所有值。)也就是說,我們想要轉置列表,其中正是內置zip的用途:

# Feed the generator to `list` to unpack and view them
list(zip(
    ['a', 'b', 'x'],
    [1, 2, 3],
    ['123', '321', '456']
))

現在我們可以勾勒出一個完整的流程:

  1. 獲取輸入的鍵和值(以相同的順序)。
  2. 轉置值。
  3. 對於轉置值中的每個序列,將該序列與鍵匹配以生成新的字典。

前兩部分很簡單:

keys, value_lists = d.keys(), d.values()
# Since the .values() are a sequence, while `zip` accepts multiple
# arguments, we need to use the `*` operator to unpack them as
# separate arguments.
grouped_values = zip(*value_lists)

最后,讓我們首先弄清楚如何從new_values一個創建單個結果字典。 從一堆鍵值對中制作 dict 很容易 - 我們可以將其直接提供給dict 然而,我們有一對序列——原始的.keys()和來自zip的結果。 顯然,解決方案是再次zip ——我們可以創建一個簡單的輔助函數來確保一切都盡可能清晰:

def new_dict(keys, values):
    return dict(zip(keys, values))

然后我們需要做的就是重復應用該函數

new_dicts = [new_dict(keys, values) for values in grouped_values]

為了炫耀,將所有內容與短名稱內聯給出:

new_dicts = [dict(zip(d.keys(), v)) for v in zip(*d.values())]

這幾乎正​​是 Jab 的答案(請注意,迭代字典給出了鍵,因此您可以直接將d而不是d.keys()傳遞給zip因為zip只會對其進行迭代)。

暫無
暫無

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

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