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!