递归生成+过滤。更好的非递归?

时间:2009-08-16 01:23:17

标签: python functional-programming recursion

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

  • 生成长度为12(可能更多)的所有可能元组,包含0,1或2(基本上是12位数的三元数)
  • 根据特定标准过滤这些元组,剔除那些不好的元素,并保留我需要的元素。

由于我必须处理很小的长度,所以函数方法简洁明了:递归函数生成所有可能的元组,然后我用过滤函数来剔除它们。现在我有一个更大的集合,生成步骤花费了太多时间,比需要的时间长得多,因为解决方案树中的大多数路径将在稍后被剔除,所以我可以跳过它们的创建。

我有两个解决方案可以解决这个问题:

  1. 将生成解密为循环,并对每个新的12位实体应用过滤条件
  2. 将过滤集成在递归算法中,以防止它进入已经注定的路径。
  3. 我的偏好是1(似乎更容易),但我想听听你的意见,特别是关注功能性编程风格如何处理这些案例。

3 个答案:

答案 0 :(得分:4)

怎么样

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)]

答案 1 :(得分:1)

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

答案 2 :(得分:0)

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