创建字符串的变体

时间:2016-08-03 14:31:30

标签: python string itertools

我生成了每个16个字符的随机字符串,并使用以下内容将它们添加到列表中:

import random
strings = []
for x in range(0, 99): 
 strings.append(''.join(random.choice('0123456789ABCDEF') for i in range(16)))

这按预期工作。现在,对于每个生成的字符串,我想找到所有可能的组合,使得至少两个字符与原始字符串保持相同,并且字符的顺序不会改变。例如,如果我们有CDD733665417E3F1,那么我想生成所有CDXXXXXXXXXXXXXX,其中X可以是任何东西(0-9或A-F)。同样XXD7XXXXXXXXXXXX等。之前的类似问题提示使用itertools.product,但我不确定如何使用它来生成排列而不是固定的替换。任何帮助将不胜感激。谢谢

1 个答案:

答案 0 :(得分:2)

使用itertools.combinations

为要保持不变的两个字符的索引创建迭代器
>>> from itertools import combinations
>>> s = 'ABC123'
>>> for indices in combinations(range(len(s)), 2):
...     print ''.join([s[x] if x in indices else 'X' for x in range(len(s))])
...
ABXXXX
AXCXXX
AXX1XX
AXXX2X
AXXXX3
XBCXXX
XBX1XX
XBXX2X
XBXXX3
XXC1XX
XXCX2X
XXCXX3
XXX12X
XXX1X3
XXXX23

创建所有变量字符串。

然后,您可以执行嵌套循环来替换X

然后,您可以使用product获取将X替换为>>> for letters in product('ABCDEF0123456789', repeat = 4): ... print letters ... ('A', 'A', 'A', 'A') ('A', 'A', 'A', 'B') ('A', 'A', 'A', 'C') ('A', 'A', 'A', 'D') ('A', 'A', 'A', 'E') ('A', 'A', 'A', 'F') ('A', 'A', 'A', '0') ('A', 'A', 'A', '1') ('A', 'A', 'A', '2') ('A', 'A', 'A', '3') ('A', 'A', 'A', '4') ('A', 'A', 'A', '5') ('A', 'A', 'A', '6') ('A', 'A', 'A', '7') ('A', 'A', 'A', '8') ('A', 'A', 'A', '9') ('A', 'A', 'B', 'A') ('A', 'A', 'B', 'B') ('A', 'A', 'B', 'C') ('A', 'A', 'B', 'D') ('A', 'A', 'B', 'E') ('A', 'A', 'B', 'F') ('A', 'A', 'B', '0') ('A', 'A', 'B', '1') ('A', 'A', 'B', '2') . . . 所需的所有字母:

>>> for indices in combinations(range(len(s)), 2):
...     for letters in product('ABCDEF0123456789', repeat = 4):
...          letter_iter = iter(letters)
...          print ''.join([s[x] if x in indices else letter_iter.next() for x in range(len(s))])

将这些组合在一起,您将获得所需的所有组合。

您可以执行以下操作:

2

注意1:您可以更改combinations调用中的repeat来更改您希望保持不变的索引数量。同样,您可以更改产品调用中的repeat = n参数以反映这些更改(n = len(s) - number_in_combinations其中product

注2:这些是愚蠢的大量值。你知道这个。请注意不要破坏你的记忆。当我进行HashMap<Integer, Color> colorsMap = new HashMap<>(); int selectedColor = Color.BLUE; public test() { .... colorsMap.put(KeyEvent.VK_B, Color.BLUE); colorsMap.put(KeyEvent.VK_R, Color.RED); colorsMap.put(KeyEvent.VK_Y, Color.YELLOW); colorsMap.put(KeyEvent.VK_G, Color.GREEN); .... } public void drawRectangle(Graphics g, int x, int y) { g.setColor(selectedColor); g.fillRect(x, y, 2, 2); } @Override public void paint(Graphics g) { .... drawRectangle(g, x, y); .... } public void keyPressed(KeyEvent e) { if(colorsMap.containsKey(e.getKeyCode())){ selectedColor = colorsMap.get(e.getKeyCode()); } } 调用时,我添加了一个索引计数器,并在索引计数器大于20后打破了循环,以避免地狱崩溃。