Home > Net >  Permute string by indices
Permute string by indices

Time:11-20

Find all distinct permutations of a string where only certain indices are allowed to be permuted.

e.g string_perms('test_world', [2,3]) --> ['test_world', 'tets_world']

I have an answer but it looks very dirty. Is there a more elegant way to do it?

from itertools import permutations

def string_perms(s, indices):
    final = []
    target = [let for ind,let in enumerate(s) if ind in indices]

    perms = list(set(permutations(target)))
    temp = list(s)

    for perm in perms:
        for ind,let in enumerate(perm):
            temp[indices[ind]] = let
        final.append(''.join(temp))
    return final

CodePudding user response:

You can use an iterator with a list comprehension:

import itertools as it
def string_perms(s, indices):
   for _i in it.permutations([s[j] for j in indices], len(indices)):
      i = iter(_i)
      yield ''.join(a if j not in indices else next(i) for j, a in enumerate(s))

print(list(string_perms('test_world', [2,3])))

Output:

['test_world', 'tets_world']

CodePudding user response:

A variant, playing with numpy direct indexing.

import numpy as np
def string_perms(s, indices):
    r = np.arange(len(s), dtype=int)
    for p in list(permutations(indices)):
        r[np.array(indices, dtype=int)] = p
        yield ''.join(np.array(list(s))[r])

print(list(string_perms('test_world', [2,3])))
print(list(string_perms("azerty", [2,4,5])))

Output:

['test_world', 'tets_world']
['azerty', 'azeryt', 'aztrey', 'aztrye', 'azyret', 'azyrte']
  • Related