字符串的所有可能排列

时间:2017-09-20 12:45:59

标签: python string

有一个字符串='january',

如何生成以下案例:

case1(替换1个字符)=> 取j并将其替换为所有ASCII字母(a-z)。然后对:a,n,u,a,r,y做同样的事。

基本上我们会有

(Aanuary,Banuary,.....,Zanuary)+(jAnuary,jBanuary ..... jZanuary)+ .... +(januarA,januarB,.....,januarZ)

我使用以下代码完成了这一部分,但是,由于存在大量的排列,我不知道如何为多个字母执行此操作。

$scope.showNewTeamDialog = function (ev) {
        $mdDialog.show({
            controller: NewTeamDialogController,
            templateUrl: 'NewTeam.html',
            locals: { newTeamName: $scope.newTeamName },
            parent: angular.element(document.body),
            targetEvent: ev
        }).then((newTeamName) => {
            if (newTeamName != undefined) {
                $scope.newTeamName = newTeamName.newTeamName;
                $scope.createNewTeam();
            }
        });

    };

案例2:取2个字符并替换它们: (AAnuary,ABnuary,.....,AZanuary)+(BAnuary,BBanuary,....,BZanuary)+(AaAuary,AaBuary,.....,AaZuary)+ ...... +(januaAB ,....,januaAZ)

案例3: 对3个字符执行相同操作

案例7: 对7个字符(字符串长度)执行相同操作

总结一下,我想创建所有可能的替换案例,1个字母,2个字母,3个字母,直到字符串的所有字母。

4 个答案:

答案 0 :(得分:1)

您可以使用itertools.combinations_with_replacement来获取iterator所有排列:

from itertools import combinations_with_replacement

# First Param is an iterable of possible values, second the length of the 
# resulting permutations
combinations = combinations_with_replacement('ABCDEFGHIJKLMNOPQRSTUVWXYZ',7)

# Then you can iterate like this:
for combination in combinations:
    #Do Stuff here

请勿尝试将此iterator转换为所有值的列表,因为您可能会获得MemoryException

您可能想要使用python distance包。 (你需要先通过pip安装它。)

对于您的情况,您希望获得长度= 7的字符a-z的所有组合(因为1月):

import distance
from itertools import combinations_with_replacement

str_to_compary_with = "JANUARY"

for i in range(len(str_to_compare_with):
    combinations = combinations_with_replacement('ABCDEFGHIJKLMNOPQRSTUVWXYZ', i+1)

    # Then you can iterate like this:
    for combination in combinations:
        # This is calculating the hamming distance for the combination with the string you want to compare to
        # Here you have to figure out yourself if you want to save that output to a file or whatever you wanna do with the distance
        hamming_dist = distance.hamming(''.join(combination), str_to_compare_with)

答案 1 :(得分:0)

如果你想知道它是如何工作的,你可以用一个字母子集测试一下,比如来自A-F:

x = []
for i in range(65,70): #subset of letters
    x.append(chr(i))

def recurse(string,index,arr):
    if(index>len(string)-1):
        return
    for i in range(index,len(string)):
        for item in x:
            temp = string[:i]+item+string[i+1:]
            arr.append(temp)
            recurse(temp,i+1,arr)

arr = []
recurse('abc',0,arr)
print arr

答案 2 :(得分:0)

这应该在productpermutations的帮助下完成您想要的一切:

from itertools import product, permutations

monthName= 'january'

letters = list('abcdefghijklmnopqrstuvwxyz')

n = len(monthName)
indxs = range(n)
mn = list(monthName)

cases = {k: [] for k in range(2, n+1)}
for num in range(2, n+1):
    letter_combos = list(product(*[letters for _ in range(num)]))
    positions = permutations(indxs, num)
    for p in positions:
        for l in letter_combos:
            l = iter(l)
            for i in p:
                mn[i] = next(l)
            mn = ''.join(mn)
            cases[num].append(mn)
            mn = list(monthName)

答案 3 :(得分:0)

很可能你不能在记忆中保留所有这些排列,因为它会很快变得非常拥挤。

但要获取案例的所有索引,您可以使用itertools.combinations。对于1,它将给出单个索引:

from itertools import combinations

string_ = 'january'
length = len(string_)
print(list(combinations(range(length), 1)))
# [(0,), (1,), (2,), (3,), (4,), (5,), (6,)]

同样,您可以获得案例2-7的索引:

print(list(combinations(range(length), 2)))
# [(0, 1), (0, 2), (0, 3), (0, 4), (0, 5), (0, 6), (1, 2), (1, 3), (1, 4), 
#  (1, 5), (1, 6), (2, 3), (2, 4), (2, 5), (2, 6), (3, 4), (3, 5), (3, 6), 
#  (4, 5), (4, 6), (5, 6)]

然后,只需在给定的索引中插入itertools.product string.ascii_uppercase

from itertools import product
import string

print(list(product(string.ascii_uppercase, repeat=1)))
# [('A',), ('B',), ('C',), ('D',), ('E',), ('F',), ('G',), ('H',), ('I',),
#  ('J',), ('K',), ('L',), ('M',), ('N',), ('O',), ('P',), ('Q',), ('R',), 
#  ('S',), ('T',), ('U',), ('V',), ('W',), ('X',), ('Y',), ('Z',)]

对于给出" case"

的不同重复,同样如此

把这一切放在一起:

def all_combinations(a_string, case):
    lst = list(a_string)
    length = len(lst)
    for combination in combinations(range(length), case):
        for inserter in product(string.ascii_uppercase, repeat=case):
            return_string = lst.copy()
            for idx, newchar in zip(combination, inserter):
                return_string[idx] = newchar
            yield ''.join(return_string)

然后,您可以通过以下方式获得所有所需的排列:

list(all_combinations('january', 2))   # case2

list(all_combinations('january', 4))   # case4

list(all_combinations('january', 7))   # case7

或者如果您需要所有这些:

res = []
for case in [1, 2, 3, 4, 5, 6, 7]:
    res.extend(all_combinations('january', case))

但这需要大量内存