用 2 个列表生成所有可能的元素组合

问题描述

考虑我们有 2 个列表(这些列表的大小可能会有所不同):

功能 = ['F1'、'F2'、'F3']
值 = [0,1]

并且我想获得任何可能大小的所有可能组合(代表它的图像):

enter image description here

我们的想法是获得所有节点(F1_0、F1_0、F2_0 ...)内所示的组合。目前,我尝试使用递归:

features = ['F1','F2','F3']
query = ''
values = [0,1]

def datatree(query,features):
    if features:
        feature = features.pop(0)
        query+= feature
        for i in values:
            datatree(query+ '_' + str(i)+' ',features)
    else:
        print(query)

datatree(query,features)

但我没有正确设计它,因为当它到达 F1_0 F2_1 并且必须继续时,特征是空的(我不明白,因为在那个子程序中堆栈应该仍然有 F3,对吧?)

Output:

F1_0 F2_0 F3_0 
F1_0 F2_0 F3_1 
F1_0 F2_1 
F1_1 

您认为还有什么其他方法可以帮助我或我无法理解的东西吗?

解决方法

原因是您只为 feature 使用了一个列表。由于featurepassed by reference,因此,例如,当您到达堆栈F_3的末尾并返回一级时,元素F_3已经被弹出并且下次您将其传递给 feature 时不在 datatree 中。

要修复它,您需要在调用 feature 时传入 datatree 的副本:

from copy import copy
features = ['F1','F2','F3']
query = ''
values = [0,1]

def datatree(query,features):
    if features:
        feature = features.pop(0)
        query+= feature
        for i in values:
            datatree(query+ '_' + str(i)+' ',copy(features))
    else:
        print(query)

datatree(query,features)

给出:

F1_0 F2_0 F3_0 
F1_0 F2_0 F3_1 
F1_0 F2_1 F3_0 
F1_0 F2_1 F3_1 
F1_1 F2_0 F3_0 
F1_1 F2_0 F3_1 
F1_1 F2_1 F3_0 
F1_1 F2_1 F3_1
,

使用 itertools.product(values,repeat=len(features)) 生成值的可能排列,例如[0,0],[0,1],...,[1,1,1]

然后使用列表推导将值作为后缀应用于相应位置的特征。我们使用 zip 将值的位置与特征匹配——即 zip(['F1','F2'],1]) 返回 [('F1',0),('F2',1)] 的可迭代对象。

from itertools import product

def datatree(features,values):
    value_combinations = product(values,repeat=len(features))
    return [
        " ".join(
            f"{feature}_{value}" for feature,value in zip(features,combination)
        )
        for combination in value_combinations
    ]

features = ['F1','F3']
values = [0,1]

# returns ['F1_0 F2_0 F3_0','F1_0 F2_0 F3_1','F1_0 F2_1 F3_0','F1_0 F2_1 F3_1','F1_1 F2_0 F3_0','F1_1 F2_0 F3_1','F1_1 F2_1 F3_0','F1_1 F2_1 F3_1']
datatree(features,values)
,

感谢所有回答这个问题的人,我能够得到所有节点的内容。这是您需要的最终代码:

features = ['F1',1]
query=''

def datatree(query,features,feature_index):
    print(query)
    if feature_index<len(features):
        query += features[feature_index]
        for i in values:
            datatree(query+ '_' + str(i)+' ',feature_index+1)
datatree(query,0)