1 回答

TA貢獻1840條經驗 獲得超5個贊
特別是我不確定...
關于在推導中更新 Python dicts 的事情有點復雜,因為它們是可變的。在為什么 python dict.update() 不返回對象?最佳答案建議您當前的解決方案。就我個人而言,我可能會在這里使用常規的 for 循環,以確保代碼清晰易讀。
這是準備測試數據的正確方法嗎?
通常在單元測試中,您將測試邊緣情況和常規情況(不過,您不想重復自己)。您通常希望拆分測試,以便每個測試都有自己的名稱來解釋它存在的原因,并且可能還有一些其他數據可以幫助某些局外人理解為什么確保此場景正確運行很重要。將所有場景放在一個列表中,然后對每個場景運行測試而不給讀者額外的上下文(至少以測試用例名稱的形式)使讀者更難區分案例并判斷它們是否全部真的需要。
將每個場景放在一個單獨的測試用例中有時看起來有點乏味,但是如果任何測試失敗,您可以立即知道軟件的哪個部分失敗了。如果您覺得自己編寫了太多單元測試,那么其中一些可能涵蓋相同類型的場景。
在處理單元測試時,性能很少是重中之重。通常更重要的是使測試數量最少,但足以確保軟件正常工作。另一個優先事項是使測試易于理解。請參閱下面的另一種看法(不一定性能更高,但希望更清晰)。
替代方案
您可以使用itertools.product
以簡化您的代碼。該template
參數可以被刪除(因為你可以通過模板變量的名字和他們可能的值**kwargs
):
from pprint import pprint
import itertools
def _f(**kwargs):
keys, values = zip(*(kwargs.items())) # 1.
subsets = [subset for subset in itertools.product(*values)] # 2.
return [
{key: value for key, value in zip(keys, subset)} for subset in subsets
] # 3.
r = _f(a=[1, 2], b=[11, 22], x=['asdf'])
pprint(r)
現在每個步驟中發生了什么:
步驟 1. 您將關鍵字 dict 拆分為鍵和值。這很重要,這樣您就可以確定每次迭代這些參數的順序。此時的鍵和值如下所示:
keys = ('a', 'b', 'x')
values = ([1, 2], [11, 22], ['asdf'])
第 2 步。您計算這些值的笛卡爾積,這意味著您可以從每個values列表中獲取一個值的所有可能組合。此操作的結果如下:
subsets = [(1, 11, 'asdf'), (1, 22, 'asdf'), (2, 11, 'asdf'), (2, 22, 'asdf')]
第 3 步?,F在您需要將每個鍵映射到每個子集中的相應值,因此列表和字典推導式,結果應該正是您使用以前的方法計算的結果:
[{'a': 1, 'b': 11, 'x': 'asdf'},
{'a': 1, 'b': 22, 'x': 'asdf'},
{'a': 2, 'b': 11, 'x': 'asdf'},
{'a': 2, 'b': 22, 'x': 'asdf'}]
添加回答
舉報