改变3个地方的所有组合
All combinations by changing 3 places
这是代码
from itertools import combinations, product
string = "abcd012345"
char = "01268abc"
for i, j in combinations(tuple(range(len(string))), 2):
for char1, char2 in product(char, char):
print(string[:i] + char1 + string[i+1:j] + char2 + string[j+1:])
我们有一个字符串 abcd012345
,我们改变两个地方以获得所有可能的组合。在这个例子中我们使用char 一组可以使用的字符。
目标是将2
改成3,以便用replacement替换3个地方,通过改3个地方找到所有可能的组合。
很高兴从您的解决方案中学习,谢谢。
让我们先讨论一下您现在正在做什么,然后我们构建一个类似的解决方案。正如您在评论中阐明的那样,您的最终目标是
compute all possible ways you could replace exactly three characters in string
with characters in char
外环
你做到了 combinations(tuple(range(len(string))), 2)
。因此,首先创建一个包含从 0
到 len(string)
的所有值的元组,然后生成由该元组中的两个值组成的所有可能组合。这里没有必要使用 tuple()
。根据 docs,combinations
的第二个参数是它应该选择一个值多少次来构建一个结果。同样在文档中,我们可以找到 combinations
不会重用结果元组的值的信息。
所以我们可以修改为
for i, j, k in combinations(range(len(string)), 3)
# generates tuples like this:
# >>> list(combinations(range(4), 3))
# [(0, 1, 2), (0, 1, 3), (0, 2, 3), (1, 2, 3)]
内循环
您从 char
中选择了两个角色。这次,根据 docs 相当于 ((x,y) for x in A for y in B)
。请注意,文档显示还有第二个可选参数:
To compute the product of an iterable with itself, specify the number of repetitions with the optional repeat keyword argument. For example, product(A, repeat=4)
means the same as product(A, A, A, A)
.
所以我们可以使用for char1, char2, char3 in product(char, repeat=3)
。在下面的例子中可以看到,这次有重复。
list(product([1,2,3,4], repeat=3))
[(1, 1, 1), (1, 1, 2), (1, 1, 3), (1, 1, 4), (1, 2, 1), (1, 2, 2), (1, 2, 3), (1, 2, 4), (1, 3, 1), (1, 3, 2), (1, 3, 3), (1, 3, 4), (1, 4, 1), (1, 4, 2), (1, 4, 3), (1, 4, 4), (2, 1, 1), (2, 1, 2), (2, 1, 3), (2, 1, 4), (2, 2, 1), (2, 2, 2), (2, 2, 3), (2, 2, 4), (2, 3, 1), (2, 3, 2), (2, 3, 3), (2, 3, 4), (2, 4, 1), (2, 4, 2), (2, 4, 3), (2, 4, 4), (3, 1, 1), (3, 1, 2), (3, 1, 3), (3, 1, 4), (3, 2, 1), (3, 2, 2), (3, 2, 3), (3, 2, 4), (3, 3, 1), (3, 3, 2), (3, 3, 3), (3, 3, 4), (3, 4, 1), (3, 4, 2), (3, 4, 3), (3, 4, 4), (4, 1, 1), (4, 1, 2), (4, 1, 3), (4, 1, 4), (4, 2, 1), (4, 2, 2), (4, 2, 3), (4, 2, 4), (4, 3, 1), (4, 3, 2), (4, 3, 3), (4, 3, 4), (4, 4, 1), (4, 4, 2), (4, 4, 3), (4, 4, 4)]
循环内容
你最后在这里做的是打印 string
除了你想要替换字符的位置。您使用内循环中的字符和外循环中的位置。如此有效,对于每两个字符(包括重复字符),您会为每一种可能的定位方式打印一个字符串(没有重复,因为您不能将它们放在同一位置)。
由于我们现在已经修改了循环生成三个位置和三个字符,我们只需要添加第三个修改。
看来我们很幸运:combinations
仅按升序生成位置元组。所以我们可以假设 i < j < k
.
print(string[:i] + char1 + string[i+1:j] + char2 + string[j+1:k] + char3 + string[k+1:])
把它们放在一起
# same as before
from itertools import combinations, product
string = "abcd012345"
char = "01268abc"
# modified as explained above
for i, j, k in combinations(range(len(string)), 3):
for char1, char2, char3 in product(char, repeat=3):
print(string[:i] + char1 + string[i+1:j] + char2 + string[j+1:k] + char3 + string[k+1:])
这将打印数千个字符串。您可能还需要考虑您是在寻找不同的输出字符串还是只是原始组合:
该解决方案只是您的 2 字符方法的概括,其中固定大小的逻辑根据参数可变。
from itertools import combinations,product
def replaceCombo(string,char,count):
for positions in combinations(range(len(string)),count):
for characters in product(char,repeat=count):
newString=list(string)
for p,c in zip(positions,characters):
newString[p]=c
yield "".join(newString)
string = "abcd012345"
char = "01268abc"
for newString in replaceCombo(string,char,2): print(newString)
00cd012345
01cd012345
02cd012345
06cd012345
... total 2,880 strings
print(len(set(replaceCombo(string,char,2)))) # 2,538 distinct strings
for newString in replaceCombo(string,char,3): print(newString)
000d012345
001d012345
002d012345
006d012345
008d012345
00ad012345
... total 61,440 strings
print(len(set(replaceCombo(string,char,3)))) # 51,094 distinct strings
这是代码
from itertools import combinations, product
string = "abcd012345"
char = "01268abc"
for i, j in combinations(tuple(range(len(string))), 2):
for char1, char2 in product(char, char):
print(string[:i] + char1 + string[i+1:j] + char2 + string[j+1:])
我们有一个字符串 abcd012345
,我们改变两个地方以获得所有可能的组合。在这个例子中我们使用char 一组可以使用的字符。
目标是将2
改成3,以便用replacement替换3个地方,通过改3个地方找到所有可能的组合。
很高兴从您的解决方案中学习,谢谢。
让我们先讨论一下您现在正在做什么,然后我们构建一个类似的解决方案。正如您在评论中阐明的那样,您的最终目标是
compute all possible ways you could replace exactly three characters in
string
with characters inchar
外环
你做到了 combinations(tuple(range(len(string))), 2)
。因此,首先创建一个包含从 0
到 len(string)
的所有值的元组,然后生成由该元组中的两个值组成的所有可能组合。这里没有必要使用 tuple()
。根据 docs,combinations
的第二个参数是它应该选择一个值多少次来构建一个结果。同样在文档中,我们可以找到 combinations
不会重用结果元组的值的信息。
所以我们可以修改为
for i, j, k in combinations(range(len(string)), 3)
# generates tuples like this:
# >>> list(combinations(range(4), 3))
# [(0, 1, 2), (0, 1, 3), (0, 2, 3), (1, 2, 3)]
内循环
您从 char
中选择了两个角色。这次,根据 docs 相当于 ((x,y) for x in A for y in B)
。请注意,文档显示还有第二个可选参数:
To compute the product of an iterable with itself, specify the number of repetitions with the optional repeat keyword argument. For example,
product(A, repeat=4)
means the same asproduct(A, A, A, A)
.
所以我们可以使用for char1, char2, char3 in product(char, repeat=3)
。在下面的例子中可以看到,这次有重复。
list(product([1,2,3,4], repeat=3))
[(1, 1, 1), (1, 1, 2), (1, 1, 3), (1, 1, 4), (1, 2, 1), (1, 2, 2), (1, 2, 3), (1, 2, 4), (1, 3, 1), (1, 3, 2), (1, 3, 3), (1, 3, 4), (1, 4, 1), (1, 4, 2), (1, 4, 3), (1, 4, 4), (2, 1, 1), (2, 1, 2), (2, 1, 3), (2, 1, 4), (2, 2, 1), (2, 2, 2), (2, 2, 3), (2, 2, 4), (2, 3, 1), (2, 3, 2), (2, 3, 3), (2, 3, 4), (2, 4, 1), (2, 4, 2), (2, 4, 3), (2, 4, 4), (3, 1, 1), (3, 1, 2), (3, 1, 3), (3, 1, 4), (3, 2, 1), (3, 2, 2), (3, 2, 3), (3, 2, 4), (3, 3, 1), (3, 3, 2), (3, 3, 3), (3, 3, 4), (3, 4, 1), (3, 4, 2), (3, 4, 3), (3, 4, 4), (4, 1, 1), (4, 1, 2), (4, 1, 3), (4, 1, 4), (4, 2, 1), (4, 2, 2), (4, 2, 3), (4, 2, 4), (4, 3, 1), (4, 3, 2), (4, 3, 3), (4, 3, 4), (4, 4, 1), (4, 4, 2), (4, 4, 3), (4, 4, 4)]
循环内容
你最后在这里做的是打印 string
除了你想要替换字符的位置。您使用内循环中的字符和外循环中的位置。如此有效,对于每两个字符(包括重复字符),您会为每一种可能的定位方式打印一个字符串(没有重复,因为您不能将它们放在同一位置)。
由于我们现在已经修改了循环生成三个位置和三个字符,我们只需要添加第三个修改。
看来我们很幸运:combinations
仅按升序生成位置元组。所以我们可以假设 i < j < k
.
print(string[:i] + char1 + string[i+1:j] + char2 + string[j+1:k] + char3 + string[k+1:])
把它们放在一起
# same as before
from itertools import combinations, product
string = "abcd012345"
char = "01268abc"
# modified as explained above
for i, j, k in combinations(range(len(string)), 3):
for char1, char2, char3 in product(char, repeat=3):
print(string[:i] + char1 + string[i+1:j] + char2 + string[j+1:k] + char3 + string[k+1:])
这将打印数千个字符串。您可能还需要考虑您是在寻找不同的输出字符串还是只是原始组合:
该解决方案只是您的 2 字符方法的概括,其中固定大小的逻辑根据参数可变。
from itertools import combinations,product
def replaceCombo(string,char,count):
for positions in combinations(range(len(string)),count):
for characters in product(char,repeat=count):
newString=list(string)
for p,c in zip(positions,characters):
newString[p]=c
yield "".join(newString)
string = "abcd012345"
char = "01268abc"
for newString in replaceCombo(string,char,2): print(newString)
00cd012345
01cd012345
02cd012345
06cd012345
... total 2,880 strings
print(len(set(replaceCombo(string,char,2)))) # 2,538 distinct strings
for newString in replaceCombo(string,char,3): print(newString)
000d012345
001d012345
002d012345
006d012345
008d012345
00ad012345
... total 61,440 strings
print(len(set(replaceCombo(string,char,3)))) # 51,094 distinct strings