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