Próbuję usunąć określone znaki z ciągu przy użyciu Pythona. Tego właśnie używam kodu. Niestety wydaje się, że nic nie robi na łańcuch.
for char in line:
if char in " ?.!/;:":
line.replace(char,'')
Jak to zrobić poprawnie?
python
string
immutability
Matt Phillips
źródło
źródło
filter
funkcji i wyrażenia lambda:filter(lambda ch: ch not in " ?.!/;:", line)
. Myślę, że dość zwięzłe i wydajne. Oczywiście zwraca nowy ciąg, któremu będziesz musiał przypisać nazwę.Odpowiedzi:
Ciągi w Pythonie są niezmienne (nie można ich zmienić). Z tego powodu efektem
line.replace(...)
jest po prostu utworzenie nowego ciągu, a nie zmiana starego. Musisz ponownie powiązać (przypisać)line
, aby zmienna przyjmowała nową wartość, a znaki zostały usunięte.Ponadto sposób, w jaki to robisz, będzie względnie powolny. Może to być nieco mylące dla doświadczonych pythonatorów, którzy zobaczą podwójnie zagnieżdżoną strukturę i pomyślą przez chwilę, że dzieje się coś bardziej skomplikowanego.
Począwszy od Python 2.6 i nowszych wersji Python 2.x *, możesz zamiast tego użyć
str.translate
(ale czytaj dalej o różnicach w Python 3):lub zamiana wyrażeń regularnych na
re.sub
Znaki w nawiasach stanowią klasę znaków . Wszelkie znaki,
line
które należą do tej klasy, są zastępowane drugim parametremsub
: pusty ciąg znaków.W Pythonie 3 ciągi znaków są Unicode. Musisz przetłumaczyć trochę inaczej. kevpie wspomina o tym w komentarzu do jednej z odpowiedzi i jest to odnotowane w dokumentacji dla
str.translate
.Podczas wywoływania
translate
metody ciągu Unicode nie można przekazać drugiego parametru, którego użyliśmy powyżej. Nie możesz również przekazaćNone
jako pierwszego parametru. Zamiast tego przekazujesz tabelę tłumaczeń (zwykle słownik) jako jedyny parametr. Ta tabela odwzorowuje wartości porządkowe znaków (tj. Wynik ich wzywaniaord
) na wartości porządkowe znaków, które powinny je zastąpić lub - co dla nas przydatne -None
aby wskazać, że należy je usunąć.Aby wykonać powyższy taniec za pomocą łańcucha Unicode, nazwałbyś coś takiego
Tutaj
dict.fromkeys
imap
służą do zwięzłego wygenerowania słownika zawierającegoJeszcze prościej, jak mówi inna odpowiedź , utwórz tabelę tłumaczeń:
Lub utwórz tę samą tabelę tłumaczeń za pomocą
str.maketrans
:* w celu zapewnienia zgodności z wcześniejszymi pythonami możesz utworzyć tabelę tłumaczeń „null”, która będzie przekazywana zamiast
None
:Tutaj
string.maketrans
służy do utworzenia tabeli translacji , która jest tylko ciągiem zawierającym znaki o wartościach porządkowych od 0 do 255.źródło
line.translate
pobiera tylko jeden argument i pierwsze rozwiązanie nie zadziałaline.translate({ord(i):None for i in '!@#$'})
"'"
dla zestawu znaków.notes = notes.translate({ord(i):None for i in '\"\''})
unicode_line.translate(str.maketrans('', '', '!@#$'))
. Lubunicode_line.translate(dict.fromkeys(map(ord, '!@#$')))
Czy brakuje mi tutaj sensu, czy jest to po prostu:
Umieść w pętli:
źródło
for char in b: a=a.replace(char,"")
string=string.replace("1","")
zamiast. W pewnym sensie powiedziałeś to w części z pętli, ale większość ludzi nie przeczyta tak daleko w twojej odpowiedzi, dopóki nie zaczną majstrować przy kodzie, aby uzyskać tak proste pytanie.źródło
blacklist = set('?:!/;')
a następnie''.join(c for c in line if c not in blacklist)
Łatwy peasy z
re.sub
regularną ekspresją jak w Pythonie 3.5Przykład
Wyjaśnienie
W wyrażeniach regularnych (regex)
|
jest logicznym OR i\
ucieka przed spacjami i znakami specjalnymi, które mogą być rzeczywistymi komendami regex. Natomiastsub
oznacza podstawienie, w tym przypadku pusty ciąg''
.źródło
W przypadku odwrotnego wymogu dopuszczania tylko niektórych znaków w ciągu można użyć wyrażeń regularnych z operatorem zbioru dopełniacza
[^ABCabc]
. Na przykład, aby usunąć wszystko oprócz liter ascii, cyfr i łącznika:Z dokumentacji wyrażeń regularnych Pythona :
źródło
Pytający prawie go miał. Jak większość rzeczy w Pythonie, odpowiedź jest prostsza niż myślisz.
Nie musisz wykonywać zagnieżdżonej pętli if / for, ale musisz sprawdzić każdy znak osobno.
źródło
źródło
źródło
Ciągi są niezmienne w Pythonie.
replace
Metoda zwraca nowy łańcuch po wymianie. Próbować:źródło
line
.Byłem zaskoczony, że nikt jeszcze nie zalecił używania wbudowanej funkcji filtra .
Powiedzmy, że chcemy odfiltrować wszystko, co nie jest liczbą. Użycie wbudowanej metody filtrowania „... jest równoważne wyrażeniu generatora (element dla elementu w iterowalnym, jeśli funkcja (element))” [ Wbudowane Python 3: Filtr ]
W Pythonie 3 to zwraca
Aby uzyskać wydrukowany ciąg,
Nie jestem pewien, jak filtrować plasuje się pod względem wydajności, ale dobrze jest wiedzieć, jak korzystać z niego podczas wykonywania list i tym podobne.
AKTUALIZACJA
Logicznie, ponieważ filtr działa, możesz również użyć analizy list i z tego, co przeczytałem, powinna być bardziej wydajna, ponieważ lambdas są menedżerami funduszy hedgingowych z Wall Street w świecie funkcji programistycznych. Kolejnym plusem jest to, że jest to jeden liniowiec, który nie wymaga żadnego importu. Na przykład, używając tego samego ciągu „s” zdefiniowanego powyżej,
Otóż to. Zwrotem będzie ciąg wszystkich znaków, które są cyframi w oryginalnym ciągu.
Jeśli masz określoną listę akceptowalnych / niedopuszczalnych znaków, musisz tylko dostosować część „jeśli” w zrozumieniu listy.
lub alternatywnie
źródło
operator.contains
jeślilambda
mimo to używasz .lambda x: operator.contains(intsList, x)
należy przeliterowaćlambda x: x in intsList
, lub jeśli próbujesz uzyskać test na poziomie C,intsList.__contains__
(wcale nielambda
).Używając
filter
, potrzebujesz tylko jednej liniiTo traktuje ciąg jako iterowalny i sprawdza każdy znak, jeśli
lambda
zwracaTrue
:źródło
Oto kilka możliwych sposobów realizacji tego zadania:
PS: Zamiast tego używając „?.! / ;:” przykłady używają samogłosek… i tak, „murcielago” to hiszpańskie słowo oznaczające nietoperz… zabawne słowo, ponieważ zawiera wszystkie samogłoski :)
PS2: Jeśli interesuje Cię wydajność, możesz zmierzyć te próby za pomocą prostego kodu, takiego jak:
W moim pudełku dostaniesz:
Wygląda na to, że próba4 jest najszybsza dla tego konkretnego wejścia.
źródło
list
sięattempt1
i krotka może być zapisane do"aeiou"
na litość prostota (usuwanie[
i]
włączy się do generatora bez tworzenia listy). Tworzysz mnóstwo wyrzucanych łańcuchów pośrednichattemt2
, używasz wielu aplikacji wyrażenia regularnego, wattempt3
których możesz użyćr'[aeiou]'
w jednym przejściu. każdy z nich ma wady - miło jest widzieć różne sposoby robienia rzeczy, ale proszę również naprawić je, aby były dobreOto moja wersja zgodna z Python 2/3. Od czasu zmiany interfejsu API tłumaczenia.
źródło
dict.fromkeys(map(ord, '!@#$'))
stworzyć mapę.map
jest ogólnie mniej czytelny niż zrozumienie listy / dict / set / generatora. Tak bardzo, że Guido chciał go usunąć z języka . Używaniefromkeys
jest również nieco sprytne i wymaga sprawdzenia dokumentacji.str.maketrans('', '', chars)
który obsługujeord
konwersję idict
budowę za jednym razem (nie wspominając o bardziej oczywistym zamiarze, ponieważ jest przeznaczony do parowaniastr.translate
).źródło
'
za ciąg. docs.python.org/2/library/re.htmlCo powiesz na to:
źródło
Możesz także użyć funkcji w celu zastąpienia innego rodzaju wyrażeń regularnych lub innego wzorca za pomocą listy. Dzięki temu możesz mieszać wyrażenia regularne, klasę znaków i naprawdę podstawowy wzorzec tekstu. Jest to bardzo przydatne, gdy trzeba zastąpić wiele elementów, takich jak HTML.
* Uwaga: działa z Python 3.x
W funkcji string_cleanup bierze twój łańcuch x, a lista niepotrzebna jako argument. Dla każdego elementu na tej liście elementów lub wzoru, jeśli potrzebny będzie zamiennik, zostanie to zrobione.
Wyjście:
źródło
Moja metoda, której użyłabym, prawdopodobnie nie działałaby tak skutecznie, ale jest niezwykle prosta. Mogę usunąć wiele znaków w różnych pozycjach jednocześnie, korzystając z krojenia i formatowania. Oto przykład:
Spowoduje to, że słowo „usunięte” będzie zawierać słowo „to”.
Formatowanie może być bardzo pomocne przy drukowaniu zmiennych w połowie ciągu wydruku. Może wstawić dowolny typ danych, używając %, po którym następuje typ danych zmiennej; wszystkie typy danych mogą używać % s , zmiennoprzecinkowe (inaczej dziesiętne), a liczby całkowite mogą używać % d .
Krojenie może być użyte do zawiłej kontroli nad łańcuchami. Kiedy wstawię słowa [: 3] , pozwala mi wybrać wszystkie znaki w ciągu od początku (dwukropek znajduje się przed liczbą, będzie to oznaczać „od początku do”) do czwartego znaku (zawiera czwarty znak postać). Powód 3 jest równy do czwartej pozycji, ponieważ Python zaczyna się od 0. Następnie, gdy wstawię słowo [-1:] , oznacza to, że na końcu znajduje się 2. ostatni znak (dwukropek znajduje się za liczbą). Ustawienie -1 spowoduje, że Python będzie liczony od ostatniego znaku, a nie od pierwszego. Ponownie Python rozpocznie się od 0. Więc słowo [-1:] zasadzie oznacza „od drugiego ostatniego znaku do końca ciągu.
Tak więc, odcinając postacie przed postacią, którą chcę usunąć, oraz postacie po i łącząc je ze sobą, mogę usunąć niechcianą postać. Pomyśl o tym jak o kiełbasie. Na środku jest brudno, więc chcę się go pozbyć. Po prostu odcinam dwa końce, które chcę, a następnie łączę je bez niechcianej części pośrodku.
Jeśli chcę usunąć wiele kolejnych znaków, po prostu przesuwam liczby w [] (część krojenia). Lub jeśli chcę usunąć wiele postaci z różnych pozycji, mogę po prostu połączyć wiele plasterków jednocześnie.
Przykłady:
usunięto równa się „cool”.
usunięto równa się „macs”.
W tym przypadku [3: 5] oznacza znak na pozycji 3 poprzez znak na pozycji 5 (z wyłączeniem znaku na końcowej pozycji).
Pamiętaj, że Python zaczyna odliczanie od 0 , więc musisz również.
źródło
Spróbuj tego:
Ta metoda działa dobrze w Pythonie 3.5.2
źródło
Możesz użyć zamiany wyrażeń regularnych w module re. Użycie wyrażenia ^ pozwala wybrać dokładnie to, co chcesz z łańcucha.
Wynikiem tego będzie „Thisisabsurd”. Pojawią się tylko rzeczy określone po symbolu ^.
źródło
Metoda ciągu
replace
nie modyfikuje oryginalnego ciągu. Pozostawia oryginał sam i zwraca zmodyfikowaną kopię.To, czego chcesz, to:
line = line.replace(char,'')
Jednak tworzenie nowego ciągu za każdym razem, gdy znak jest usuwany, jest bardzo nieefektywne. Zamiast tego polecam następujące:
źródło
Poniżej jednego… bez użycia wyrażenia regularnego…
źródło
W Python 3.5
na przykład,
Aby usunąć całą liczbę z ciągu
źródło
możesz użyć zestawu
źródło
Podział rekurencyjny: s = ciąg; znaki = znaki do usunięcia
przykład:
źródło
# dla każdego pliku w katalogu, zmień nazwę pliku
źródło
Nawet poniższe podejście działa
wynik:
abcde
źródło
źródło