列表字典的笛卡尔积
我正在尝试编写一些代码来测试一堆输入参数的笛卡尔积。
我查看了 itertools
,但它的 product
功能并不完全是我想要的。是否有一种简单明显的方法来获取具有任意数量的键和每个值中任意数量的元素的字典,然后生成具有下一个排列的字典?
输入:
options = {"number": [1,2,3], "color": ["orange","blue"] }
print list( my_product(options) )
示例输出:
[ {"number": 1, "color": "orange"},
{"number": 1, "color": "blue"},
{"number": 2, "color": "orange"},
{"number": 2, "color": "blue"},
{"number": 3, "color": "orange"},
{"number": 3, "color": "blue"}
]
I'm trying to write some code to test out the Cartesian product of a bunch of input parameters.
I've looked at itertools
, but its product
function is not exactly what I want. Is there a simple obvious way to take a dictionary with an arbitrary number of keys and an arbitrary number of elements in each value, and then yield a dictionary with the next permutation?
Input:
options = {"number": [1,2,3], "color": ["orange","blue"] }
print list( my_product(options) )
Example output:
[ {"number": 1, "color": "orange"},
{"number": 1, "color": "blue"},
{"number": 2, "color": "orange"},
{"number": 2, "color": "blue"},
{"number": 3, "color": "orange"},
{"number": 3, "color": "blue"}
]
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

发布评论
评论(5)
风筝有风,海豚有海2024-10-27 22:06:44
Seth 的答案的 Python 3 版本。
import itertools
def dict_product(options):
"""
>>> list(dict_product({'number': [1, 2], 'character': 'ab'}))
[{'character': 'a', 'number': 1},
{'character': 'a', 'number': 2},
{'character': 'b', 'number': 1},
{'character': 'b', 'number': 2}]
"""
return (dict(zip(options.keys(), x)) for x in itertools.product(*options.values()))
我也只是我2024-10-27 22:06:44
# I would like to do
keys,values = options.keys(), options.values()
# but I am not sure that the keys and values would always
# be returned in the same relative order. Comments?
keys = []
values = []
for k,v in options.iteritems():
keys.append(k)
values.append(v)
import itertools
opts = [dict(zip(keys,items)) for items in itertools.product(*values)]
结果
opts = [
{'color': 'orange', 'number': 1},
{'color': 'orange', 'number': 2},
{'color': 'orange', 'number': 3},
{'color': 'blue', 'number': 1},
{'color': 'blue', 'number': 2},
{'color': 'blue', 'number': 3}
]
分分钟2024-10-27 22:06:44
这就是我想到的:
from itertools import product
def dctproduct(dct):
"""
>>> list(dctproduct({'number': [1, 2], 'character': 'ab'}))
[{'number': 1, 'character': 'a'}, {'number': 1, 'character': 'b'}, {'number': 2, 'character': 'a'}, {'number': 2, 'character': 'b'}]
"""
keys = dct.keys()
for vals in product(*dct.values()):
yield dict(zip(keys, vals))
这也可以用于有效地调用具有关键字参数的所有组合的函数:
def kwproduct(**kwargs):
"""
>>> for kwargs in kwproduct(number=[1, 2], character='ab'):
>>> print(kwargs)
{'number': 1, 'character': 'a'}
{'number': 1, 'character': 'b'}
{'number': 2, 'character': 'a'}
{'number': 2, 'character': 'b'}
"""
return dctproduct(kwargs)
kwproduct
相对于 dictproduct
的好处是你不需要不需要创建一个 dict
但它显然限制您使用有效的参数名称作为键。
~没有更多了~
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
好的,谢谢@dfan 告诉我我找错地方了。我现在明白了:
编辑:经过多年的Python经验,我认为更好的解决方案是接受
kwargs
而不是输入字典;调用风格更类似于原始的itertools.product。另外,我认为编写生成器函数,而不是返回生成器表达式的函数,可以使代码更清晰。所以:如果你需要传入一个字典,
list(product_dict(**mydict))
。使用 kwargs 而不是任意输入类的一个显着变化是它会阻止键/值排序,至少在 Python 3.6 之前是这样。Ok, thanks @dfan for telling me I was looking in the wrong place. I've got it now:
EDIT: after years more Python experience, I think a better solution is to accept
kwargs
rather than a dictionary of inputs; the call style is more analogous to that of the originalitertools.product
. Also I think writing a generator function, rather than a function that returns a generator expression, makes the code clearer. So:and if you need to pass in a dict,
list(product_dict(**mydict))
. The one notable change usingkwargs
rather than an arbitrary input class is that it prevents the keys/values from being ordered, at least until Python 3.6.