Python 字符串的所有可能排列

Python 字符串的所有可能排列,python,string,Python,String,有一个字符串='一月', 如何生成以下案例: case1(替换1个字符)=>取j并替换为所有ASCII字母(a-z)。然后对a,n,u,a,r,y做同样的处理 基本上我们会 (一年一次,平日,…,平日)+(一月一日,…,平日)+…+(一月一日,…,一月一日) 我已经使用以下代码完成了这一部分,但是,我不知道如何对多个字母执行此操作,因为有很多排列 案例2:取2个字符并替换它们: (一年一次的,异常的,…,一年一次的)+(一年一次的,一年一次的,…,一年一次的)+(一年一次的,一年一次的,…,一

有一个字符串='一月',

如何生成以下案例:

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

基本上我们会

(一年一次,平日,…,平日)+(一月一日,…,平日)+…+(一月一日,…,一月一日)

我已经使用以下代码完成了这一部分,但是,我不知道如何对多个字母执行此操作,因为有很多排列


案例2:取2个字符并替换它们: (一年一次的,异常的,…,一年一次的)+(一年一次的,一年一次的,…,一年一次的)+(一年一次的,一年一次的,…,一年一次的)+(一年一次的,一年一次的,…,一年一次的)+(januaAB,…,januaAZ)

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

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


总之,我想创建所有可能的替换案例,1个字母、2个字母、3个字母,最多替换字符串中的所有字母

如果你想知道它是如何工作的,你可以用字母子集来测试它,比如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

为此,您可以使用
itertools.compositions\u和\u replacement
,这将为您提供一个具有所有排列的
迭代器:

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
不要试图将此
迭代器
转换为所有值的列表,因为您可能会得到
MemoryException

对于距离,您可能需要使用python
distance
package。(您需要先通过pip进行安装)

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


产品
排列
的帮助下,这应该可以完成您想要的一切:

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)

很可能你无法在内存中保存所有这些排列,因为它会很快变得非常拥挤

但要获得案例的所有索引,可以使用
itertools.combines
。对于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)]
然后,只需在给定索引处插入
string.ascii_大写的
itertools.product

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',)]
同样,对于给定“情况”的不同重复

综上所述:

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

但这将需要大量的内存

因此,在案例1中,您将有7个
“一月”
s?您的意思是用相似的字母替换选定的字母?(例如:一月,将a替换为a)如果是,如果我们可以避免替换为同一个字母,那就更好了,否则我可以在创建所有排列后处理这部分。@WillemVanOnsemIsn这不就是a-z中7个字符的字符串的所有可能排列吗?是的,是的。我现在将更改标题。谢谢@IgleIn我的情况是我更改了字符,我们还能将其计算为“所有可能的排列”?因为在我检查了“所有排列”的情况下,他们只是考虑同一字符串的所有不同排列,而不改变任何字符(如ABC、ACB、CAB等)。@IgleI需要在月份名称中创建某种噪音(替换字母),然后计算编辑距离(levenshtein,hamming,…)通过比较原始字符串和嘈杂的字符串。为此,我需要考虑替换字母的所有可能性,考虑到要替换的字母数目和噪声的位置。是否需要每个可能组合的距离或者仅仅是最高的、最低的、任何的距离?基本上是针对每一个可能的组合,然而,你是否有一个?如果我只选择最低的一个,有什么建议吗?我的意思是,这在创建所有排列的意义上有什么区别吗?@IgleThanks,将尝试并对结果进行评论。@zipaThanks很多人,我已经尝试了两个案例,效果很好。但是我会一直坚持到最后,并会让你知道我的笔记本是否还活着:)干得好,顺便说一句,竖起大拇指;)
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))