尽管“if statement”,重复项最终仍在列表中

时间:2016-07-05 17:58:30

标签: python python-3.x

好的,我正在编写一个代码,可以为您输入的加扰字母提供所有可能的组合。这是:

import random, math

words = []
original = raw_input("What do you need scrambled? ")

def word_scramble(scrambled):

    original_length = len(scrambled)
    loops = math.factorial(original_length)

    while loops > 0:
        new_word = []

        used_numbers = []

        while len(new_word) < original_length:

            number = random.randint(0, original_length - 1)

            while number in used_numbers:
                number = random.randint(0, original_length - 1)

            while number not in used_numbers:
                used_numbers.append(number)
                new_word.append(scrambled[number])

        if new_word not in words:
            words.append(("".join(str(x) for x in new_word)))
            loops -= 1

word_scramble(original)

print ("\n".join(str(x) for x in words))

问题是,它仍然提供重复,即使它不应该。例如,我可以输入“imlk”并且有时会获得两次“牛奶”,同时仍然只给出24个排列,这意味着排除了一些排列。 :

if new_word not in words:
    words.append(("".join(str(x) for x in new_word)))
    loops -= 1

应该可以防止副本出现在列表中。所以我不确定问题是什么。对不起,问题的主题是如此模糊/怪异。我不太确定如何更好地表达它。

4 个答案:

答案 0 :(得分:6)

itertools.permutations怎么样?

import itertools
original = raw_input("What do you need scrambled? ")
result = [''.join(s) for s in itertools.permutations(original)]

答案 1 :(得分:3)

if new_word not in words:
    words.append(("".join(str(x) for x in new_word)))
    loops -= 1

new_word是一个字母列表,但words包含字符串而不是字母列表。它们采用不同的格式,因此检查将始终成功。

例如,您可能会收到支票:

if ['m', 'i', 'l', 'k'] not in ['imlk', 'milk', 'klim']

而不是

if 'milk' not in ['imlk', 'milk', 'klim']

顺便说一句,你的算法将会非常严重地扩展它需要加扰的字母。它依赖于随意绊倒未使用的单词,这一开始很快,但使用的单词越多越慢。

如果你能想出一种在没有猜测的情况下以可预测的顺序枚举排列的方法,你会感觉更好。

答案 2 :(得分:2)

来自doc

  

itertools.permutations(iterable [,r])

     

返回迭代中元素的连续r长度排列。

     

如果未指定r或为None,则r默认为长度   可迭代且生成所有可能的全长排列。

import itertools
word=raw_input()
scramble_all = [''.join(p) for p in itertools.permutations(word)]
print scramble_all

<强>输出:

  

[&#39;牛奶&#39;,&#39; mikl&#39;,&#39; mlik&#39;,&#39; mlki&#39;,&#39; mkil&#39;,& #39; mkli&#39;,&#39; imlk&#39;,&#39; imkl&#39;,   &#39; ilmk&#39;,&#39; ilkm&#39;,&#39; ikml&#39;,&#39; iklm&#39;,&#39; lmik&#39;,&#39; lmki& #39;,&#39; limk&#39;,&#39; likm&#39;,   &#39; lkmi&#39;,&#39; lkim&#39;,&#39; kmil&#39;,&#39; kmli&#39;,&#39; kiml&#39;,&#39; kilm& #39;,&#39; klmi&#39;,&#39; klim&#39;]

答案 3 :(得分:0)

无视原始问题,我可以为生成所有组合提供更好的解决方案。提醒一下,所有可能的组合排列之间存在差异。

组合是来自某些集合的元素子集的排序无关紧要的地方。例如,“bac”和“abc”是相同的组合。对于排序很重要的排列,情况恰恰相反,“abc”和“bac”不是相同的排列。组合是集合的所有可能子集,而排列是集合的所有可能排序。

考虑到这一点,这里有一个生成集合的所有可能组合(子集)的算法。

def all_subsets( L ):
    if L == []:
        return []
    result = []
    for i in range( len ( L ) ):
        result += [ [ L[ i ] ] ]
        result += [ e + [ L[ i ] ] for e in all_subsets( L[ i+1 : ] ) ]
    return result