9

今日、この問題について考えていたところ、次の疑似コード (Python 3.2) がありました。

def anagrams( string ):

    for c in string:
      anagram = c + anagram( string - {c} ) # remove the char from its position in the string
      print(anagram)

    return

def main():

    word = "abcd"
    anagrams( word )

    return

ただし、この操作を実行する Pythonic な方法を知りたい: anagram = c + anagram( string - {c} )

文字列からその文字を削除するにはどうすればよいですか? たとえば、次のようになります。

"abc" -> 'a' + "bc" -> 'a' + 'b' + "c" -> 'a' + 'b' + 'c' = 'abc'
             + "cb" -> 'a' + 'c' + "b" -> 'a' + 'c' + 'b' = 'acb'
      -> 'b' + "ac" -> 'b' + 'a' + "c" -> 'b' + 'a' + 'c' = 'bac'
             + "ca" -> 'b' + 'c' + "a" -> 'b' + 'c' + 'a' = 'bca'
      -> 'c' + "ba" -> 'c' + 'b' + "a" -> 'c' + 'b' + 'a' = 'cba'
             + "ab" -> 'c' + 'a' + "b" -> 'c' + 'a' + 'b' = 'cab'

ありがとう

4

5 に答える 5

28

itertoolsだけを使用しないのはなぜですか?

>>> import itertools
>>> ["".join(perm) for perm in itertools.permutations("abc")]
['abc', 'acb', 'bac', 'bca', 'cab', 'cba']

ドキュメントには、順列がどのように行われるかのコードも含まれています。


編集:

なしitertools:

def all_perms(elements):
    if len(elements) <=1:
        yield elements
    else:
        for perm in all_perms(elements[1:]):
            for i in range(len(elements)):
                yield perm[:i] + elements[0:1] + perm[i:]


word = "abc"
print list(all_perms(word))

なしitertoolsとなしgenerators:

def all_perms(elements):
    if len(elements) <=1:
        return elements
    else:
        tmp = []
        for perm in all_perms(elements[1:]):
            for i in range(len(elements)):
                tmp.append(perm[:i] + elements[0:1] + perm[i:])
        return tmp

結果:

['abc', 'bac', 'bca', 'acb', 'cab', 'cba']

于 2012-08-16T14:39:27.910 に答える
6

モジュールを使用しitertoolsます。

import itertools
perms = [''.join(perm) for perm in itertools.permutations('abc')]
于 2012-08-16T14:39:21.567 に答える
4

文字列に文字の複数のインスタンスが含まれている場合、@slothの答えは少し予期しない結果をもたらします-重複した順列:

["".join(perm) for perm in itertools.permutations('aabc')]

結果:

['aabc',
 'aacb',
 'abac',
 'abca',
 'acab',
 'acba',
 'aabc',
 'aacb',
 'abac',
 'abca',
 'acab',
 'acba',
 'baac',
 'baca',
 'baac',
 'baca',
 'bcaa',
 'bcaa',
 'caab',
 'caba',
 'caab',
 'caba',
 'cbaa',
 'cbaa']

これが望ましい結果でない場合は、'set' を使用すると重複が解消されます。ただし、リストが必要な場合は、再リストする必要があります (また、「set」は順序を維持しないため、「sorted」を使用します):

sorted(set(["".join(perm) for perm in itertools.permutations("aabc")]))

結果:

['aabc',
 'aacb',
 'abac',
 'abca',
 'acab',
 'acba',
 'baac',
 'baca',
 'bcaa',
 'caab',
 'caba',
 'cbaa']
于 2016-11-10T02:41:52.000 に答える
0

単語をリストにキャストし、removeを実行してから、joinを使用して再びまとめることができます。

word = 'abca'
letters = list(word)
letters.remove('a')  # Only deletes the first 'a'
word = ''.join(letters)
于 2012-08-16T14:41:35.763 に答える