2014-12-11 109 views
0

假設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中做到這一點?我可以在一個循環中做到這一點,我必須使用遞歸,或者我必須(只有在沒有其他方式)的代碼對象?

+2

對於foo中的j是什麼意思? 'foo'顯然是一個枚舉,所以我不知道'foo - i'是什麼。 – ganbustein 2014-12-11 03:02:12

+0

好吧,我們知道'foo'是可迭代的,並且假設列表類行爲,'i'是'foo'中的一個項 - 我們無法猜測'foo - i'的含義。 – 2014-12-11 03:04:42

+0

對不起,我會更清楚。 – tox123 2014-12-11 03:09:08

回答

1

你的問題與combinatorics有關。具體笛卡爾產品。

沒有遞歸,你需要知道你要運行多少個循環的嵌套。但是,您不需要提前知道這些信息。只要你能動態地得到它就沒問題。

考慮我的回購協議的一個採取這樣的代碼: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可以動態構建,並且不一定是字典。如果您修改了我的代碼,您可以使用其他結構的列表輕鬆地指定值。

上述代碼中的魔術歸結爲itertools.product函數的使用。我建議你看看那個。 https://docs.python.org/2/library/itertools.html#itertools.product