Каждый символ заменить из строки в Python

1

Я новичок в программировании... Мой код очень прост. Скажем, мой номер "123", тогда я хочу получить "abc". Проверить, где я ошибаюсь

def number2char(number):
    search_array = ["1", "2", "3", "4", "5", "6", "7", "8", "9", "0"]
    replace_array = ["a", "b", "c", "d", "d", "e", "f", "g", "h", "i"]
    num_2_char = number.replace(search_array, replace_array);
    return num_2_char;  

Здесь я получаю ошибку

num_2_char = number.replace(search_array, replace_array); TypeError: ожидается, что объект буфера символов

Пожалуйста, помогите мне...

Теги:
string
replace

3 ответа

2

Проблема заключается в том, что str.replace заменяет одну подстроку str.replace. То, что означает ошибка: он хочет подстроку, и вы дали ей список отдельных символов.


Вы можете перебрать пары замены, вызвав replace для каждого из них:

>>> s = '123'
>>> for search, replace in zip(search_array, replace_array):
...     s = s.replace(search, replace)
>>> s
'abc'

Или вы можете просто использовать str.translate, который действительно делает то, что вы хотите, хотя для этого требуется немного настройки:

>>> search_array = ["1", "2", "3", "4", "5", "6", "7", "8", "9", "0"]
>>> replace_array = ["a", "b", "c", "d", "d", "e", "f", "g", "h", "i"]
>>> trans = str.maketrans(dict(zip(search_array, replace_array)))
>>> '123'.translate(trans)
'abc'

Или, альтернативно, и, вероятно, более читаемым:

>>> search = "1234567890"
>>> replace = "abcddefghi"
>>> trans = str.maketrans(search, replace)
>>> '123'.translate(trans)
'abc'

Кстати, если это не преднамеренно, что вы указали d два раза подряд, может быть яснее (и сложнее сделать эту опечатку!), Чтобы указать такие буквы:

>>> replace = string.ascii_lowercase[:10]
1

Вместо этого вы можете использовать словарь. Здесь несколько шагов:

  1. Мы хотим сопоставить каждое число символу, поэтому мы можем создать словарь с входными символами в виде ключей и выходными символами в качестве значений.
  2. Вы не можете перебирать числовой ввод, поэтому нам нужно преобразовать его в строку для доступа к каждому символу по очереди. В вашем примере значение уже является строкой ('123'), но нет причин, по которым вы не можете заставить функцию принимать как числовые, так и строковые входы.
  3. Замена выполняется в понимании списка, которое, естественно, возвращает список. Поэтому вам нужно вызвать join() чтобы объединить все символы вместе в одну строку.

Один из подходов состоит в следующем:

def number2char(number):
    search_array = ["1", "2", "3", "4", "5", "6", "7", "8", "9", "0"]
    replace_array = ["a", "b", "c", "d", "d", "e", "f", "g", "h", "i"]
    replace_dict = dict(zip(search_array, replace_array))
    num_2_char = ''.join([replace_dict.get(char, '_') 
                          for char in str(number)])
    return num_2_char

a = number2char(123)

В этом случае я использовал replace_dict.get(str(item), '_') чтобы код не replace_dict если кто-то дает вход, который не находится в replace_dict; вместо этого они просто вернут подчеркивания. Вероятно, есть более эффективные способы справиться с этим, но это безопаснее, чем просто пытаться получить доступ к словарю как replace_dict[item].

  • 0
    Отличное объяснение и очень полезно. Большое спасибо @roganjosh
  • 0
    О чем пункт 2? ОП говорит, что ввод 123' , который является строкой. Плюс, если бы это была не строка, он не получил бы TypeError который получил, он получил бы AttributeError .
Показать ещё 16 комментариев
0
def number2char(number):
    search_array = ["1", "2", "3", "4", "5", "6", "7", "8", "9", "0"]
    replace_array = ["a", "b", "c", "d", "d", "e", "f", "g", "h", "i"]
    num_2_char=''
    for i in number:
        num_2_char +=  replace_array[search_array.index(i)]
    return num_2_char;
  • 0
    Это действительно не очень хорошее решение. Почти каждый раз, когда вы вызываете index в списке, это признак того, что вы используете либо неправильную структуру данных, либо неправильный алгоритм. Здесь вы могли бы просто использовать dict вместо линейного поиска по каждому символу каждый раз - это было бы проще, яснее по смыслу и даже более эффективно (не то, чтобы здесь это имело значение). Но в этот момент вы только что получили ответ Роганьоша.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню