假设foo
是一个列表或其他迭代器。我想要一些东西,以便我可以(伪代码):
for i in foo
for j in foo - [i]
for k in foo - [i, j]
...
for some_var in foo - [i, j, k, ...]//only one value left in foo
do_something(some_args)
有没有办法在python中执行此操作?我是否可以在循环中执行此操作,是否必须使用递归,或者我是否必须(仅在没有其他方式)编写代码对象?
答案 0 :(得分:1)
你的问题与组合学有关。特别是笛卡尔产品。
如果没有递归,您需要知道要运行多少个循环嵌套。但是,您不需要提前了解此信息。只要你能动态地获得它就可以了。
请考虑从我的其中一个回购中获取此代码:https://github.com/Erotemic/utool/blob/next/utool/util_dict.py
from itertools import product
import six
varied_dict = {
'logdist_weight': [0.0, 1.0],
'pipeline_root': ['vsmany'],
'sv_on': [True, False, None]
}
def all_dict_combinations(varied_dict):
tups_list = [[(key, val) for val in val_list]
for (key, val_list) in six.iteritems(varied_dict)]
dict_list = [dict(tups) for tups in product(*tups_list)]
return dict_list
dict_list = all_dict_combinations(varied_dict)
运行此代码将导致dict_list为
[
{'pipeline_root': 'vsmany', 'sv_on': True, 'logdist_weight': 0.0},
{'pipeline_root': 'vsmany', 'sv_on': True, 'logdist_weight': 1.0},
{'pipeline_root': 'vsmany', 'sv_on': False, 'logdist_weight': 0.0},
{'pipeline_root': 'vsmany', 'sv_on': False, 'logdist_weight': 1.0},
{'pipeline_root': 'vsmany', 'sv_on': None, 'logdist_weight': 0.0},
{'pipeline_root': 'vsmany', 'sv_on': None, 'logdist_weight': 1.0},
]
然后你可以编写像
这样的代码 for some_vars in dict_list:
do_something(some_vars)
如果你要列出foo可以在我称之为vary_dict的每个嵌套级别中列出的每个值,那么你可以找到你的问题的解决方案。另请注意,vary_dict可以动态构建,并且它实际上不必是dict。如果您修改了我的代码,您可以使用其他结构列表轻松指定值。
上面代码中的神奇之处在于使用了itertools.product函数。我建议你看一下。 https://docs.python.org/2/library/itertools.html#itertools.product