user2061944 user2061944 - 1 year ago 71
Python Question

Create variations of a string

I generated random strings of 16-characters each and added them to a list using the following:

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

This worked as expected. Now, for each generated string, I want to find all possible combinations such that at least two characters remain same as the original string and the order of characters does not change. For example, if we have CDD733665417E3F1, then I want to generate all CDXXXXXXXXXXXXXX where X could be anything (0-9 or A-F). Similarly XXD7XXXXXXXXXXXX and so on. Previous similar questions hint towards using
but I am not sure how it can be used to generate permutations and not fixed replacements. Any help will be appreciated. Thank you

Answer Source

Create an iterator for the indices of the two characters you want to stay the same using 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))])

Creates all the variable strings.

You can then do a nested loop to replace the X's.

Then you can use product to get all the letters that you would need to replace the X's with:

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

Combine these together and you would get all the combinations of what you want.

You can probably do something like:

>>> 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 for x in range(len(s))])

NOTE 1: you can change the 2 in the call of combinations to change the amount of indices you want to stay the same. Likewise, you can change the repeat parameter in the call to product to reflect those changes (repeat = n where n = len(s) - number_in_combinations)

NOTE 2: These are stupidly large amounts of values. You know this. Please be careful that you don't destroy your memory. When I did the product call, I added an index counter and broke the loop after the index counter got greater than 20 to avoid hell breaking loose.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download