python - комбинации замены символов со списком

Я пытаюсь создать список слов, который содержит все возможные комбинации замены символов путем замены нескольких символов соответствующими списками. Вход также является списком ключевых слов. Пример:

keywords=["magic", "mate"]

aoptions = ["a", "4", "@"]
boptions = ["b", "8"]
eoptions = ["e", "3"]
goptions = ["g", "9"]
ioptions = ["i", "1"]
loptions = ["l", "1"]
ooptions = ["o", "0"]
soptions = ["s", "5", "$"]
toptions = ["t", "7"]
zoptions = ["z", "2"]

Желаемым результатом будет список вроде этого:

['magic', 'mag1c', 'ma9ic', 'ma91c'...'m@t3', 'm@73']

Мне удалось создать решение только для одного ключевого слова и заменить один символ другим одним. Алгоритм был найден здесь Комбинации замены строк. Это выглядит так

from itertools import product

def filler(word, from_char, to_char):
   options = [(c,) if c != from_char else (from_char, to_char) for c in word]
   return (''.join(o) for o in product(*options))

Что приводит к:

>>> filler("magic", "a", "4")
<generator object <genexpr> at 0x8fa798c>
>>> list(filler("magic", "a", "4"))
['magic', 'm4gic']

Это не особенно важно, но список ключевых слов будет считываться из файла.txt с одним ключевым словом в каждой строке, а результирующий список комбинаций будет записываться в файл.txt с одним словом в каждой строке. Я пытался создавать разные итеративные циклы и модифицировать пример itertools.product в течение нескольких дней без какой-либо удачи. Любая помощь очень ценится.

ОБНОВЛЕНИЕ: Обновление моей функции наполнителя на основе совета #zefciu, который я смог решить, используя этот метод:

from itertools import product

def filler(word):
   combos = [(c,) if c not in options else options[c] for c in word]
   return (''.join(o) for o in product(*combos))

options = {
  'A': ['A', '4', '@'],
  'B': ['B', '8',],
  'E': ["E", "3"],
  'G': ["G", "9"],
  'I': ["I", "1", "!"],
  'L': ["L", "1"],
  'O': ["O", "0"],
  'S': ["S", "5", "$"],
  'T': ["T", "7"],
  'Z': ["Z", "2"]}

with open('CustomList.txt', 'r') as f:
   startlist = f.readlines()
startlist = [x.strip() for x in startlist]
startlist = [element.upper() for element in startlist]

filid= open('WordList.txt', 'w+')
for word in startlist:
   temp_list=list(filler(word))
for newword in temp_list:
   print >> filid, newword
filid.close()

3 ответа

Решение

Прежде всего, не храните данные такого рода в отдельных переменных. Эти данные запрашивают данные как:

options = {
    'a': ['a', '4', '@'],
    'y': ['y', 'ყ'],
}

Таким образом, вам нужно всего лишь немного изменить функцию. Вместо проверки идентичности с одним значением, проверьте, есть ли оно в вашем словаре:

[c,] if c not in options else options[c]

Итерация + рекурсия.

Учитывая только одно слово, "магия".

Посмотрите на каждую букву по очереди. магия. (Итерация). Это в списке букв, которые можно заменить? Если так, сделайте замену и сохраните замещенную форму в списке результатов. Теперь, если это последняя буква в "магии", продолжайте итерацию, иначе начните рекурсивное снижение, сохраняя этот выбор буквы в этой позиции, но развлекая все возможные варианты для следующей заменяемой буквы.

И так до завершения.

Могут быть и другие подходы, но так как вы начали с одного, я продолжу с этим.

def filler_list(word_list, from_char, to_char):
   return_list=[]
   for word in word_list:
      return_list=return_list+list(filler(word,from_char,to_char))
   return return_list

Затем просто зациклите каждый символ, т. Е. Начните со списка (filler("magic", "a", "4")) и передайте его вывод в filler_list при изменении ввода и символа, и так вы получите ответ, который может быть с некоторые повторяются, но они могут быть удалены, если не нужно, надеюсь, это поможет Cheers!

Другие вопросы по тегам