简体   繁体   English

为什么修改后的笛卡尔乘积函数不能用于Python?

[英]Why doesn't this modified Cartesian Product function for Python work?

Ideally, the input is [1,2], and the output is all combinations [[1,1], [2,2], [1,2], [2,1]]. 理想情况下,输入为[1,2],输出为所有组合[[1,1],[2,2],[1,2],[2,1]]。 Basically, print all possible combinations with replacement. 基本上,打印所有可能的替换组合。

def cart(lst):
   if lst == []:
      return [[]]

   return [x[i:] + [lst[0]] + x[:i] for x in cart(lst[1:]) for i in range(len(x)) ]

l = [1,2,3] 
print cart(l)

Returns 退货

[] []

In more human-readable form, the code basically says: 该代码基本上以更易于理解的形式表示:

for x in cart(lst[1:]):
   for i in range(len(x)):
      return x[i:] + [lst[0]] + x[:i]

And if we assume the recursive case with input [1,2,3] , then cart([2,3]) should produce [[2,3], [3,2], [2,2], [3,3]] , and so for the recursive step we would want to insert 1 in every possible location. 如果我们假设递归的情况是输入[1,2,3] ,则cart([2,3])应该产生[[2,3], [3,2], [2,2], [3,3]] ,因此对于递归步骤,我们希望在每个可能的位置插入1 (This code might be missing the 111 case.) (此代码可能缺少111情况。)

The code appears logically correct, but outputs an empty string. 该代码在逻辑上看似正确,但是输出一个空字符串。

Is there something missing or am I approaching the problem incorrectly? 是否缺少某些东西,或者我处理问题的方式不正确?

Edit 编辑

Actually, I realize the code would be slightly more complicated: 实际上,我意识到代码会稍微复杂一些:

def cart(lst):
    if len(lst) <= 1:
        return lst
    else:
        return [x[i:] + [lst[j]] + x[:i] for x in cart(lst[1:]) for j in range(len(lst)) for i in range(len(x))]

Although this still strangely returns an empty list. 尽管这仍然奇怪地返回了一个空列表。 My hunch is that I am missing a base case. 我的直觉是我缺少一个基本案例。

Edit 编辑

It was something to do with my base case. 这与我的基本情况有关。 Revised code: 修改后的代码:

def cart(lst):
    if len(lst) <= 1:
        return [lst]
    else:
        return [x[i:] + [lst[j]] + x[:i] for x in cart(lst[1:]) for j in range(len(lst)) for i in range(len(x))]

l = [1,2,3]
print cart(l)

But now returns 但是现在返回

[[3, 2, 1], [2, 1, 3], [3, 2, 2], [2, 2, 3], [3, 2, 3], [2, 3, 3], [3, 3, 1 ], [3, 1, 3], [3, 3, 2], [3, 2, 3], [3, 3, 3], [3, 3, 3]] [[3,2,1],[2,1,3],[3,2,2],[2,2,3],[3,2,3],[2,3,3],[ 3,3,1],[3,1,3],[3,3,2],[3,2,3],[3,3,3],[3,3,3]]

Better now, although the output is missing sets. 现在更好了,尽管输出缺少集合。 Seems like a base case issue again. 似乎又是一个基本案例问题。

Found the answer here Algorithm for recursive function for permutations with replacement in python 在此处找到答案在python中使用置换替换的递归函数算法

def permutations_with_replacement(k,n):
         # special case (not part of recursion)
         if k == 0:
            return []

         if k == 1:
            return [[n[i]] for i in range(len(n))]

         else:
            # Make the list by sticking the k-1 permutations onto each number 
            # we can select here at level k    
            result = []
            # Only call the k-1 case once, though we need it's output n times.
            k_take_one_permutations = permutations_with_replacement(k-1,n)  

            for i in range(len(n)):
                for permutation in k_take_one_permutations:
                    result.append([n[i]]+permutation)   
            return result

         print permutations_with_replacement(3,2)

print permutations_with_replacement(3, [1,2,3])

It appears I was trying to take the recursive case of the list itself, rather than the size of the combinations. 看来我正在尝试采用列表本身的递归形式,而不是组合的大小。

I'm wondering whether or not the solution would be do-able by recurring on the list, rather than the size of the combinations. 我想知道解决方案是否可以通过重复出现在列表上而不是组合的大小来实现。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM