Как уже упоминалось, проблема, с которой вы сталкиваетесь, связана с тем, что каждый символ в s
безоговорочно заменяет «чистый» - поскольку a
и b
состоят из одинаковых букв, а str.replace(x, y)
заменяет ВСЕ вхождения x
с y
, некоторые символы снова и снова «расшифровываются» ...
Первый шаг к правильному решению - создать новую строку вручную вместо использования str.replace
:
def decipher(s):
result = []
for char in s:
for index, crypted in enumerate(a):
if char == crypted:
result.append(b[index])
# no need to go further
break
else:
# The else clause of a for loop is only executed
# if the for loop runs to the end without being
# interrupted by a break statement.
#
# Here we use it to handle the case of whitespaces
# or any other char that's in `s` but not in `a`
result.append(c)
return "".join(result)
Теперь, хотя это даст ожидаемые результаты, оно бесполезно сложно и очень неэффективно. То, что вы делаете, это, по сути, отображение - в этом случае отображение зашифрованных символов на дешифрованные - поэтому очевидным решением здесь является использование Python основного mapping
встроенного введите : a dict
:
CLEAR = 'abcdefghijklmnopqrstuvwxyz'
CRYPT = 'defghijklmnopqrstuvwxyzabc'
DECIPHER_MAP = dict(zip(CRYPT, CLEAR))
def decipher(s):
## the 'unrolled' version:
# result = []
# for c in s:
# result.append(DECIPHER_MAP.get(c, c))
# return "".join(result)
# which is even simpler _and_ faster (and uses less memory)
# using a generator expression.
return "".join(DECIPHER_MAP.get(c, c) for c in s)
Как видите, алгоритм на намного проще. Это также намного быстрее (поиск dict 0 (1) и высоко оптимизирован), и потребляет меньше памяти (нет необходимости для промежуточного списка result
).
В программировании выбор правильной структуры данных является ключевым ...
NB:
теперь мне интересно понять ошибку МОЕГО кода.
Это очень похвально, если не сказать больше - Я бы sh все здесь сделали бы то же самое. Теперь это то, что вы могли бы решить самостоятельно с помощью самой простой и простой c технологии отладки c: отслеживание выполнения кода путем распечатки вашего текущего состояния в стратегии c моменты:
def deciph(s):
for i in s:
print("i : '{}' - s : '{}'".format(i, s))
for j in range(len(a)):
if i==a[j]:
print("i == '{}' - replacing with '{}'".format(i, b[j]))
s = s.replace(i, b[j])
print("now s : '{}'".format(s))
return s
>>> deciph("pme")
i : 'p' - s : 'pme'
i == 'p' - replacing with 'm'
now s : 'mme'
i : 'm' - s : 'mme'
i == 'm' - replacing with 'j'
now s : 'jje'
i : 'e' - s : 'jje'
i == 'e' - replacing with 'b'
now s : 'jjb'
'jjb'