我最近才了解使用生成器的協程,并嘗試在以下遞回函式中實作該概念:
def _recursive_nWay_generator(input: list, output={}):
'''
Helper function; used to generate parameter-value pairs
to submit to the model for the simulation.
Parameters
----------
input : list of tuple
every tuple of the list must be of the form:
``('name_of_parameter', iterable_of_values)``
output : list, optional
parameter used for recursion; allows for list building
across subgenerators
Returns
-------
Generator :
Specifications used for simulation setup of the form:
``{'par1': val1, ...}``
'''
# exit condition
if len(input) == 0:
yield output
# recursive loop
else:
curr = input[0]
par_name = curr[0]
for par_value in curr[1]:
output[par_name] = par_value
# coroutines for the win!
yield from _recursive_nWay_generator(input[1:], output=output)
功能有點按預期作業:
testlist = [('a', (1, 2, 3)), ('b', (4, 5, 6)), ('c', (7, 8))]
for a in _recursive_nWay_generator(testlist):
print(a)
輸出:
{'a': 1, 'b': 4, 'c': 7}
{'a': 1, 'b': 4, 'c': 8}
{'a': 1, 'b': 5, 'c': 7}
{'a': 1, 'b': 5, 'c': 8}
{'a': 1, 'b': 6, 'c': 7}
{'a': 1, 'b': 6, 'c': 8}
{'a': 2, 'b': 4, 'c': 7}
{'a': 2, 'b': 4, 'c': 8}
{'a': 2, 'b': 5, 'c': 7}
{'a': 2, 'b': 5, 'c': 8}
{'a': 2, 'b': 6, 'c': 7}
{'a': 2, 'b': 6, 'c': 8}
{'a': 3, 'b': 4, 'c': 7}
{'a': 3, 'b': 4, 'c': 8}
{'a': 3, 'b': 5, 'c': 7}
{'a': 3, 'b': 5, 'c': 8}
{'a': 3, 'b': 6, 'c': 7}
{'a': 3, 'b': 6, 'c': 8}
但是,當我嘗試附加到現有串列或構建新串列時,它會中斷:
gen = _recursive_nWay_generator(testlist)
print(list(gen))
輸出:
[{'a': 3, 'b': 6, 'c': 8}, {'a': 3, 'b': 6, 'c': 8}, {'a': 3, 'b': 6, 'c': 8}, {'a': 3, 'b': 6, 'c': 8}, {'a': 3, 'b': 6, 'c': 8}, {'a': 3, 'b': 6, 'c': 8}, {'a': 3, 'b': 6, 'c': 8}, {'a': 3, 'b': 6, 'c': 8}, {'a': 3, 'b': 6, 'c': 8}, {'a': 3, 'b': 6, 'c': 8}, {'a': 3, 'b': 6, 'c': 8}, {'a': 3, 'b': 6, 'c': 8}, {'a': 3, 'b': 6, 'c': 8}, {'a': 3, 'b': 6, 'c': 8}, {'a': 3, 'b': 6, 'c': 8}, {'a': 3, 'b': 6, 'c': 8}, {'a': 3, 'b': 6, 'c': 8}, {'a': 3, 'b': 6, 'c': 8}]
這個問題試圖做一些接近我所擁有的事情,但我沒有看到有幫助的答案。
老實說,我對如何解決這個問題一無所知,無論我如何表述這個問題,我嘗試的在線搜索都沒有給出任何結果。如果在我之前回答了這個問題,我會很樂意點擊鏈接。
uj5u.com熱心網友回復:
output您的代碼的問題是在迭代和遞回呼叫期間重用相同的可變字典。也就是說,您yield output然后稍后修改它,output[par_name] = par_value但在每種情況下它都是相同的字典 - 所以您正在修改已經回傳的實體!如果您將每個結果附加到一個串列中,然后在最后列印它們,您會發現它們是相同的——每次產生的結果都是一樣的。
“修復”現有代碼的最簡單方法是生成副本,即更改行:
yield output
進入這個:
yield dict(output.items())
但是,這個演算法不是很好,我建議你尋找更好的演算法。在這里使用遞回是糟糕的選擇。我將為您提供一種更有效地生成序列的簡單/直接方法:
import itertools as it
testlist = [('a', (1, 2, 3)), ('b', (4, 5, 6)), ('c', (7, 8))]
keys, vals = zip(*testlist)
for p in it.product(*vals):
print(dict(zip(keys, p)))
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/537095.html
