簡體   English   中英

需要用數組值分解python字典

[英]Need to break down a python dictionary with array values

我有一個 python 字典,看起來像:

dictionary = {
    'a' : ['@'],
    's' : ['$', '5', 'z'],
    'o' : ['0', '()']
}

我需要將其分解為:

   [{
     'a' : ['@'],
     's' : ['$'],
     'o' : ['0']
    },
    {
     'a' : ['@'],
     's' : ['5'],
     'o' : ['0']
    },
    {
     'a' : ['@'],
     's' : ['z'],
     'o' : ['0']
    },
    {
     'a' : ['@'],
     's' : ['$'],
     'o' : ['()']
    },
    {
     'a' : ['@'],
     's' : ['5'],
     'o' : ['()']
    },
    {
     'a' : ['@'],
     's' : ['z'],
     'o' : ['()']
    }]

字典中的所有鍵都有一個字符串列表的值,解決方案必須將每個列表的項目分解為單獨的字符串,並在考慮所有可能的組合的同時生成一個鍵有一個值的新字典。

並且該解決方案必須適用於所有大小的類似字典。

itertools.product是獲得所有組合的顯而易見的方法,但這里的挑戰是它以錯誤的順序產生排列。 如果您反轉函數的輸入和輸出,這將給出所需的順序。

您還希望輸出子字典中的值是單元素列表; 在這里,這是由字典理解中的[v] (代替僅v )處理的。

from pprint import pprint
from itertools import product

dictionary = {
    'a' : ['@'],
    's' : ['$', '5', 'z'],
    'o' : ['0', '()']
}

out =  [
    {k:[v] for k, v in zip(dictionary.keys(), reversed(x))}
    for x in product(*reversed(list(dictionary.values())))
]

pprint(out)

給出:

[{'a': ['@'], 'o': ['0'], 's': ['$']},
 {'a': ['@'], 'o': ['0'], 's': ['5']},
 {'a': ['@'], 'o': ['0'], 's': ['z']},
 {'a': ['@'], 'o': ['()'], 's': ['$']},
 {'a': ['@'], 'o': ['()'], 's': ['5']},
 {'a': ['@'], 'o': ['()'], 's': ['z']}]

(注意:實際上,對於支持此功能的 Python 版本,即 >= 3.7,每個字典的元素將按正確的順序排列,盡管在這里我使用的是按字母順序對字典鍵進行排序的pprint版本。)

spam = {
    'a' : ['@'],
    's' : ['$', '5', 'z'],
    'o' : ['0', '()']
}

from itertools import product
eggs = [dict(zip(spam.keys(), ([sub_item] for sub_item in item)))
        for item in product(*spam.values())]
print(eggs)

輸出

[{'a': ['@'], 's': ['$'], 'o': ['0']}, {'a': ['@'], 's': ['$'], 'o': ['()']}, {'a': ['@'], 's': ['5'], 'o': ['0']}, {'a': ['@'], 's': ['5'], 'o': ['()']}, {'a': ['@'], 's': ['z'], 'o': ['0']}, {'a': ['@'], 's': ['z'], 'o': ['()']}]

您可以將遞歸與生成器一起用於無導入解決方案:

def combos(d, c = []):
  if not d:
    yield dict(c)
  else:
    yield from [i for a, b in d[0] for i in combos(d[1:], c+[(a, [b])])]

d = {'a': ['@'], 's': ['$', '5', 'z'], 'o': ['0', '()']}
print(list(combos([[[a, i] for i in b] for a, b in d.items()])))

輸出:

[{'a': ['@'], 's': ['$'], 'o': ['0']}, {'a': ['@'], 's': ['$'], 'o': ['()']}, {'a': ['@'], 's': ['5'], 'o': ['0']}, {'a': ['@'], 's': ['5'], 'o': ['()']}, {'a': ['@'], 's': ['z'], 'o': ['0']}, {'a': ['@'], 's': ['z'], 'o': ['()']}]

暫無
暫無

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

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