Próbuję usunąć określone znaki z łańcucha za pomocą Pythona. To jest kod, którego używam w tej chwili. Niestety wygląda na to, że nic nie robi z ciągiem.
for char in line:
if char in " ?.!/;:":
line.replace(char,'')
Jak mogę to zrobić poprawnie?
Łańcuchy w Pythonie są immutable (nie mogą'być zmieniane). Z tego powodu, efektem działania line.replace(...)
jest po prostu stworzenie nowego łańcucha, a nie zmiana starego. Musisz rebind (przypisać) go do line
, aby zmienna przyjęła nową wartość, z usuniętymi znakami.
Ponadto, sposób w jaki to robisz będzie dość powolny, relatywnie. Może też być nieco mylący dla doświadczonych użytkowników Pythona, którzy widząc podwójnie zagnieżdżoną strukturę będą przez chwilę myśleć, że dzieje się coś bardziej skomplikowanego.
Począwszy od Pythona 2.6 i nowszych wersji Pythona 2.x *, możesz zamiast tego użyć str.translate
, (ale czytaj dalej o różnicach w Pythonie 3):
line = line.translate(None, '!@#$')
lub zamianę wyrażeń regularnych za pomocą re.sub
import re
line = re.sub('[!@#$]', '', line)
Znaki ujęte w nawiasy tworzą klasę znaków. Wszystkie znaki w line
, które należą do tej klasy, są zastępowane drugim parametrem sub
: pustym łańcuchem.
W Pythonie 3, łańcuchy są Unicode. Będziesz musiał tłumaczyć trochę inaczej. kevpie wspomina o tym w komentarzu do jednej z odpowiedzi, a to'jest zauważone w dokumentacji dla str.translate
.
Podczas wywoływania metody translate
dla łańcucha Unicode, nie można przekazać drugiego parametru, którego użyliśmy powyżej. Nie możesz także'przekazać None
jako pierwszego parametru, ani nawet tablicy translacji z string.maketrans
. Zamiast tego, przekazujesz słownik jako jedyny parametr. Słownik ten odwzorowuje wartości porządkowe znaków (tj. wynik wywołania ord
na nich) na wartości porządkowe znaków, które powinny je zastąpić, lub - co jest dla nas bardzo użyteczne - None
, aby wskazać, że powinny zostać usunięte.
Tak więc, aby wykonać powyższy taniec z łańcuchem Unicode, wywołałbyś coś w rodzaju
translation_table = dict.fromkeys(map(ord, '!@#$'), None)
unicode_line = unicode_line.translate(translation_table)
Tutaj dict.fromkeys
i map
są użyte do zwięzłego wygenerowania słownika zawierającego
{ord('!'): None, ord('@'): None, ...}
Jeszcze prościej, jak inna odpowiedź to ujmuje, utwórz słownik w miejscu:
unicode_line = unicode_line.translate({ord(c): None for c in '!@#$'})
* Dla kompatybilności z wcześniejszymi Pythonami, możesz utworzyć "null" tablicę translacji, aby przekazać ją w miejsce None
:
import string
line = line.translate(string.maketrans('', ''), '!@#$')
Tutaj string.maketrans
jest używany do tworzenia tablicy translacji, która jest po prostu łańcuchem zawierającym znaki o wartościach porządkowych od 0 do 255.