Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/340.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 递归生成&x2B;过滤。更好的非递归?_Python_Functional Programming_Recursion - Fatal编程技术网

Python 递归生成&x2B;过滤。更好的非递归?

Python 递归生成&x2B;过滤。更好的非递归?,python,functional-programming,recursion,Python,Functional Programming,Recursion,我有以下需要(在python中): 生成所有可能的长度为12(可能更多)的元组,其中包含0、1或2(基本上是一个具有12位数字的三元数) 根据特定的标准过滤这些元组,剔除那些不好的元组,并保留我需要的元组 由于到目前为止我必须处理较小的长度,函数方法简洁明了:递归函数生成所有可能的元组,然后我用过滤函数剔除它们。现在我有了一个更大的集合,生成步骤花费了太多的时间,比需要的时间长得多,因为解决方案树中的大多数路径稍后将被剔除,因此我可以跳过它们的创建 我有两种解决方案: 将生成过程分解为一个循

我有以下需要(在python中):

  • 生成所有可能的长度为12(可能更多)的元组,其中包含0、1或2(基本上是一个具有12位数字的三元数)
  • 根据特定的标准过滤这些元组,剔除那些不好的元组,并保留我需要的元组
由于到目前为止我必须处理较小的长度,函数方法简洁明了:递归函数生成所有可能的元组,然后我用过滤函数剔除它们。现在我有了一个更大的集合,生成步骤花费了太多的时间,比需要的时间长得多,因为解决方案树中的大多数路径稍后将被剔除,因此我可以跳过它们的创建

我有两种解决方案:

  • 将生成过程分解为一个循环,并对每个新的12位实体应用筛选条件
  • 将过滤集成到递归算法中,以防止其进入已注定的路径
  • 我倾向于1(似乎更简单),但我想听听你的意见,特别是关于函数式编程风格如何处理此类情况的看法。

    怎么样

    import itertools
    
    results = []
    for x in itertools.product(range(3), repeat=12):
        if myfilter(x):
            results.append(x)
    
    其中,
    myfilter
    进行选择。这里,例如,只允许10个或更多1的结果

    def myfilter(x):  # example filter, only take lists with 10 or more 1s
        return x.count(1)>=10
    
    也就是说,我的建议是你的选择1。在某些情况下,它可能会慢一些,因为(取决于您的条件)您可能会生成许多不需要的列表,但它更通用,并且非常容易编码

    编辑:正如hughdbrown在评论中所建议的那样,这种方法还有一种单行形式:

    results = [x for x in itertools.product(range(3), repeat=12) if myfilter(x)]
    
    怎么样

    import itertools
    
    results = []
    for x in itertools.product(range(3), repeat=12):
        if myfilter(x):
            results.append(x)
    
    其中,
    myfilter
    进行选择。这里,例如,只允许10个或更多1的结果

    def myfilter(x):  # example filter, only take lists with 10 or more 1s
        return x.count(1)>=10
    
    也就是说,我的建议是你的选择1。在某些情况下,它可能会慢一些,因为(取决于您的条件)您可能会生成许多不需要的列表,但它更通用,并且非常容易编码

    编辑:正如hughdbrown在评论中所建议的那样,这种方法还有一种单行形式:

    results = [x for x in itertools.product(range(3), repeat=12) if myfilter(x)]
    

    itertools
    具有处理此问题的功能。但是,以下是一种(硬编码)处理发电机的方法:

    T = (0,1,2)
    
    GEN = ((a,b,c,d,e,f,g,h,i,j,k,l) for a in T for b in T for c in T for d in T for e in T for f in T for g in T for h in T for i in T for j in T for k in T for l in T)
    
    for VAL in GEN:
        # Filter VAL
        print VAL
    

    itertools
    具有处理此问题的功能。但是,以下是一种(硬编码)处理发电机的方法:

    T = (0,1,2)
    
    GEN = ((a,b,c,d,e,f,g,h,i,j,k,l) for a in T for b in T for c in T for d in T for e in T for f in T for g in T for h in T for i in T for j in T for k in T for l in T)
    
    for VAL in GEN:
        # Filter VAL
        print VAL
    

    我会实现一个迭代的二进制加法器或汉明码并以那种方式运行。

    我会实现一个迭代的二进制加法器或汉明码并以那种方式运行。

    一行列表理解:结果=[x代表itertools.product中的x(范围(3),如果myfilter(x)]一行列表理解:结果=[x代表itertools.product中的x(范围(3),重复=12)如果myfilter(x)]