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

У меня есть что-то вроде ниже:

invalid_chars = [' ', ',', ';', '{', '}', '(', ')', '\\n', '\\t', '=']
word = 'Ad{min > HR'
for c in list(word):
  if c in invalid_chars:
    word = word.replace(c, '_')
print (word) 

>>> Admin_>_HR

Я пытаюсь преобразовать это в функцию, используя понимание списка, но я странные персонажи ...

def replace_chars(word, checklist, char_replace = '_'):
  return ''.join([word.replace(ch, char_replace) for ch in list(word) if ch in checklist])

print(replace_chars(word, invalid_chars))
>>> Ad_min > HRAd{min_>_HRAd{min_>_HR
0
Cryssie 1 Июл 2019 в 05:12

3 ответа

Лучший ответ

Попробуйте этот общий шаблон:

''.join([ch if ch not in invalid_chars else '_' for ch in word])

Для полной функции:

def replace_chars(word, checklist, char_replace = '_'):
  return ''.join([ch if ch not in checklist else char_replace for ch in word])

Примечание: нет необходимости переносить строку word в list(), она уже повторяется.

3
tchainzzz 1 Июл 2019 в 02:20

Это может быть полезно для str.translate(), Вы можете превратить свой invalid_chars в таблицу перевода с помощью {{ X2}} и применяйте там, где вам это нужно:

invalid_chars = [' ', ',', ';', '{', '}', '(', ')', '\n', '\t', '=']
invalid_table = str.maketrans({k:'_' for k in invalid_chars})

word = 'Ad{min > HR'

word.translate(invalid_table)

< Сильный > Результат :

'Ad_min_>_HR'

Это будет особенно хорошо, если вам нужно применить этот перевод к нескольким строкам и сделать его более эффективным, поскольку вам не нужно перебирать весь массив invalid_chars для каждой буквы, каждый раз, когда вы будете использовать {{X1) }} внутри цикла.

3
Mark Meyer 1 Июл 2019 в 03:15

Это проще с регулярным выражением. Вы можете искать целую группу символов с помощью одного вызова подстановки. Это должно работать лучше тоже.

>>> import re
>>> re.sub(f"[{re.escape(''.join(invalid_chars))}]", "_", word)
'Ad_min_>_HR'

Код в f-строке создает шаблон регулярного выражения, который выглядит следующим образом

>>> pattern = f"[{re.escape(''.join(invalid_chars))}]"
>>> print(repr(pattern))
'[\\ ,;\\{\\}\\(\\)\\\n\\\t=]'
>>> print(pattern)
[\ ,;\{\}\(\)\
\   =]

То есть набор символов регулярных выражений, содержащий каждый из ваших недопустимых символов. (Выход из обратной косой черты гарантирует, что ни один из них не будет интерпретирован как управляющий символ регулярного выражения, независимо от того, какие символы вы поместили в invalid_chars.) Если вы указали их как строку в первую очередь, ''.join() не потребуется.

Вы также можете скомпилировать шаблон (используя re.compile()), если вам нужно повторно использовать его для нескольких слов.

2
gilch 1 Июл 2019 в 03:02