簡體   English   中英

如何計算 Python 中 N 個不同詞典的所有組合

[英]How can I calculate all combinations of N different dictionaries in Python

挑戰

我需要將各種詞典組合在一起以獲得所有可能的組合,同時還需要一種可以采用 (N) 個詞典的方法。 我有以下適用於單個案例的代碼,但我正在尋找更優雅和可擴展的解決方案。

當前解決方案

這適用於指定數量的字典(配置文件、環境、test_vars):

profile = {
    "normal": {"profile": "normal"},
    "special": {"profile": "special"}
}

environment = {
    "legacy": {"id": 123},
    "staging": {"id": 123, "sid": 123123},
    "production": {"pid": 14941729}
}

test_vars = {
    "no_tests": {"var1": ""},
    "var1:prod": {"var1": "prod"},
    "var1+var2": {"var1": "alpha", "var2": "alpha"},
    "var2_beta": {"var2": "beta"},
    "var2_alpha": {"var2": "alpha"}
}

total = [
    {"{}|{}|{}".format(pk, ek, tk): {**pv, **ev, **tv}}
    for pk, pv in profile.items()
    for ek, ev in environment.items()
    for tk, tv in test_vars.items()
]

result = [{id: '&'.join(["{}={}".format(i, x) for i, x in v.items()])
  for id, v in condition.items()}
 for condition in total]

result

結果

output 看起來像這樣,其中列表的每個元素指定一個“測試標識符”和表示為查詢字符串參數的“測試變量”。

Out[68]: 
[{'normal|legacy|no_tests': 'profile=normal&id=123&var1='},
 {'normal|legacy|var1:prod': 'profile=normal&id=123&var1=prod'},
 {'normal|legacy|var1+var2': 'profile=normal&id=123&var1=alpha&var2=alpha'},
 {'normal|legacy|var2_beta': 'profile=normal&id=123&var2=beta'},
 {'normal|legacy|var2_alpha': 'profile=normal&id=123&var2=alpha'},
 {'normal|staging|no_tests': 'profile=normal&id=123&sid=123123&var1='},
 {'normal|staging|var1:prod': 'profile=normal&id=123&sid=123123&var1=prod'},
 {'normal|staging|var1+var2': 'profile=normal&id=123&sid=123123&var1=alpha&var2=alpha'},
 {'normal|staging|var2_beta': 'profile=normal&id=123&sid=123123&var2=beta'},
 {'normal|staging|var2_alpha': 'profile=normal&id=123&sid=123123&var2=alpha'},
 {'normal|production|no_tests': 'profile=normal&pid=14941729&var1='},
 {'normal|production|var1:prod': 'profile=normal&pid=14941729&var1=prod'},
 {'normal|production|var1+var2': 'profile=normal&pid=14941729&var1=alpha&var2=alpha'},
 {'normal|production|var2_beta': 'profile=normal&pid=14941729&var2=beta'},
 {'normal|production|var2_alpha': 'profile=normal&pid=14941729&var2=alpha'},...

我的問題

這不能擴展到添加更多的配置字典。

假設我現在想添加另一個配置字典,比如release 我必須添加那個新的字典,並像這樣修改“總”理解:

total = [
    {"{}|{}|{}|{}".format(pk, ek, tk, rk): {**pv, **ev, **tv, **rv}}
    for pk, pv in profile.items()
    for ek, ev in environment.items()
    for tk, tv in test_vars.items()
    for rk, rv in release_vars.items()
]

這似乎不夠優雅,尤其是當我可以處理 00 的配置字典時。

任何人都可以幫助 devise 一些更具可擴展性的東西嗎?

你可以嘗試這樣的事情:

from itertools import product
def t(*args):
    counter = len(args)
    tmp  = [i.keys() for i in args]

    s =  {"|".join(i): [l[k] for l,k in zip(args,i)] for i in product(*tmp)}

    for k, v in s.items():
         s[k] = "&".join(["%s=%s"%(v1,v2) for j in v for v1,v2 in j.items()])
    return s

from pprint import pprint
pprint(t(profile, environment, test_vars))

結果:

{'normal|legacy|no_tests': 'profile=normal&id=123&var1=',
 'normal|legacy|var1+var2': 'profile=normal&id=123&var1=alpha&var2=alpha',
 'normal|legacy|var1:prod': 'profile=normal&id=123&var1=prod',
 'normal|legacy|var2_alpha': 'profile=normal&id=123&var2=alpha', ...

PS 這不是最好的解決方案,但它可以擴展,祝你好運:)

暫無
暫無

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

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