亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

通過理解更新列表中的字典項

通過理解更新列表中的字典項

慕碼人8056858 2021-09-14 20:36:51
我有一本字典,我想用它作為模板來生成多個帶有更新字典項的字典。此列表應用作 pytest 中單元測試中用于測試目的的數據集。我在我的代碼中使用以下構造(不包括檢查):def _f(template,**kwargs):    result = [template]    for key, value in kwargs.items():        result = [dict(template_item,**dict([(key,v)])) for v in value for template_item in result]    return resulttemplate = {'a': '', 'b': '', 'x': 'asdf'}r = _f(template, a=[1,2],b=[11,22])pprint(r)[{'a': 1, 'b': 11, 'x': 'asdf'}, {'a': 2, 'b': 11, 'x': 'asdf'}, {'a': 1, 'b': 22, 'x': 'asdf'}, {'a': 2, 'b': 22, 'x': 'asdf'}]我想問一下,該構造是否用于構建足夠好 - 可能它可以寫得更有效。這是準備測試數據的正確方法嗎?編輯: 特別是我不確定[dict(template_item,**dict([(key,v)])) for v in value for template_item in result]和dict(template_item,**dict([(key,v)])) 在我考慮 dict.update() 但不適合理解之前,因為它不返回字典。然后我在考慮簡單的語法,比如d = {'aa': 11, 'bb': 22}dict(d,x=33,y=44)    {'aa': 11, 'bb': 22, 'x': 33, 'y': 44}但我無法通過變量傳遞鍵值。創建 dict 只是為了解壓它對我來說聽起來適得其反。
查看完整描述

1 回答

?
慕斯709654

TA貢獻1840條經驗 獲得超5個贊

特別是我不確定...

關于在推導中更新 Python dicts 的事情有點復雜,因為它們是可變的。在為什么 python dict.update() 不返回對象?最佳答案建議您當前的解決方案。就我個人而言,我可能會在這里使用常規的 for 循環,以確保代碼清晰易讀。

這是準備測試數據的正確方法嗎?

  1. 通常在單元測試中,您將測試邊緣情況和常規情況(不過,您不想重復自己)。您通常希望拆分測試,以便每個測試都有自己的名稱來解釋它存在的原因,并且可能還有一些其他數據可以幫助某些局外人理解為什么確保此場景正確運行很重要。將所有場景放在一個列表中,然后對每個場景運行測試而不給讀者額外的上下文(至少以測試用例名稱的形式)使讀者更難區分案例并判斷它們是否全部真的需要。

  2. 將每個場景放在一個單獨的測試用例中有時看起來有點乏味,但是如果任何測試失敗,您可以立即知道軟件的哪個部分失敗了。如果您覺得自己編寫了太多單元測試,那么其中一些可能涵蓋相同類型的場景。

  3. 在處理單元測試時,性能很少是重中之重。通常更重要的是使測試數量最少,但足以確保軟件正常工作。另一個優先事項是使測試易于理解。請參閱下面的另一種看法(不一定性能更高,但希望更清晰)。

替代方案

您可以使用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'}]


查看完整回答
反對 回復 2021-09-14
  • 1 回答
  • 0 關注
  • 219 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號