Bezdepbonusu7Программирование: статьи и ответы

Вопрос

TypeError при использовании replace() из словаря

Автор вопроса: MoeghoegОтветов: 4

Прежде всего: пожалуйста, имейте в виду, что я очень новичок в программировании.

Я пытаюсь написать простую программу на Python, которая заменит согласные в строке на согласную + "о" + согласную. Например, "b" будет заменено на "bob", а "d" будет заменено на "dod" (поэтому слово "python" будет заменено на "popytothohonon").

Для этого я создал словарь, содержащий пары b:bob,c:coc,d:dod и т. д. Затем я использовал команду replace(), чтобы прочитать слово и заменить согласные на их перевод в словаре. Полный фрагмент кода выглядит так:

def replacer(text):
    consonant='bcdfghjklmnpqrstvwxz'
    lexicon={}
    for x in range(0,len(consonant)):
        lexicon[x]=(consonant[x]),(consonant[x]+'o'+consonant[x])
    for i,j in lexicon.items():
        text=(text.replace(i,j))
    return text

Теперь, когда я пытаюсь вызвать эту функцию, я получаю следующую ошибку:

Traceback (most recent call last):
  File "D:\x\x.py", line 37, in <module>
      print(replacer("python"))
  File "D:\x\x.py", line 17, in replacer
      text=(text.replace(i,j))
TypeError: Can't convert 'int' object to str implicitly

Но я не использую целые числа! Со словарем должно быть что-то не так, потому что все работает, когда я делаю это "вручную" вот так:

list={'b':'bob', 'c':'coc', 'd':'dod', 'f':'fof', 'g':'gog', 'h':'hoh'......}

Но когда печатаю "нерукотворный" словарь вроде бы все в порядке:

{0: ('b', 'bob'), 1: ('c', 'coc'), 2: ('d', 'dod'), 3: ('f', 'fof')........

Что я делаю не так?

pythondictionarystringtypeerrorint

Ответы

Ответ 1 · рейтинг 3 · mgilson

lexicon - это словарь с целыми числами в качестве ключей и кортежами в качестве значений. когда вы перебираете его элементы, вы получаете кортежи формы (integer,tuple). Затем вы передаете это целое число и кортеж в text.replace как i и j, поэтому он жалуется. Возможно, вы имели в виду:

 for i,j in lexicon.values():
     ...

Для этой простой замены подойдет str.replace, но для более сложных замен код, вероятно, будет более надежным (и, возможно, выполняться быстрее!), если вы используйте вместо этого re.sub.


Кроме того, как указано в комментариях, в этом случае лучшей структурой данных было бы использование list:

lexicon = [ (x,'{0}o{0}'.format(x)) for x in chars ]

Теперь вы можете построить свой dict из этого списка, если вы действительно хотите:

lexicon = dict(enumerate(lexicon))

но наверное не надо. И в этом случае вы бы перебрали lexicon напрямую:

for i,j in lexicon:
    ...

Если вы собираетесь сделать это только один раз, вы можете даже сделать это лениво, даже не материализуя список, используя выражение генератора:

lexicon = ( (x,'{0}o{0}'.format(x)) for x in chars )

Ответ 2 · RobertT

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

lexicon = { c: c+'o'+c for c in consonant }

что эквивалентно:

for c in consonant:
  lexicon[c] = c+'o'+c

Ответ 3 · Aprillion

На этот раз словари не нужны, просто перебирайте символы текста, добавляйте гласные или согласные + о + согласные в результирующий массив и присоединяйте его к строке в конце:

def replacer(text):
    consonants = set('bcdfghjklmnpqrstvwxz')
    result = []
    for c in text:
        if c in consonants:
            result.append(c+"o"+c)
        else:
            result.append(c)
    return "".join(result)

print(replacer("python"))

Для опытных пользователей:
def replacer(text):
    return re.sub(r"[bcdfghjklmnpqrstvwxz]", r"\g<0>o\g<0>", text)

А на ответ "Что я делаю не так?" - словари полезны для произвольных ключей, обычно list.append() предпочтительнее использовать ключи 0-n в словаре. И поскольку вас не интересует позиция согласного, вы можете перебирать строки напрямую следующим образом:
for x in consonant:
    lexicon[x] = x+"o"+x

Ответ 4 · рейтинг -1 · Joran Beasley

нет... ваши ключи в самодельной версии - строки... ваши кеты в другой версии - целые... целые не имеют метода замены

Перевод вопроса и ответов сообщества Stack Overflow, лицензия CC BY-SA. Оригинал на Stack Overflow.

Похожие материалы