Jak uzyskać podciąg ciągu znaków w Pythonie?

2142

Czy istnieje sposób na podciąganie łańcucha w Pythonie, aby uzyskać nowy ciąg od trzeciego znaku do końca ciągu?

Może jak myString[2:end]?

Jeśli opuszczenie drugiej części oznacza „do końca”, a jeśli opuścisz pierwszą część, to czy zacznie się od początku?

Joan Venge
źródło
1
Ten zawiera jasne wyjaśnienie pythoncentral.io/cutting-and-slicing-strings-in-python
mario ruiz

Odpowiedzi:

3178
>>> x = "Hello World!"
>>> x[2:]
'llo World!'
>>> x[:2]
'He'
>>> x[:-2]
'Hello Worl'
>>> x[-2:]
'd!'
>>> x[2:-2]
'llo Worl'

Python nazywa tę koncepcję „krojeniem” i działa na więcej niż tylko łańcuchach. Spójrz tutaj kompleksowego wprowadzenia.

Paolo Bergantino
źródło
401

Tylko dla kompletności, jak nikt inny o tym nie wspomniał. Trzecim parametrem wycinka tablicy jest krok. Tak więc odwrócenie łańcucha jest tak proste jak:

some_string[::-1]

Lub wybór alternatywnych znaków to:

"H-e-l-l-o- -W-o-r-l-d"[::2] # outputs "Hello World"

Możliwość przechodzenia do przodu i do tyłu przez ciąg zachowuje spójność z możliwością ustawiania wycinka od początku lub końca.

Endofag
źródło
21
@mtahmed absolutnie związany z pytaniem. Co jeśli chcesz podciągać, wybierając alternatywne znaki z ciągu? To byłoby my_string [:: 2]
Endophage
Myślę, że bardziej prawdopodobne jest, że chciałbyś wspomnieć o trzecim parametrze do krojenia. Konieczność uzyskania każdej innej postaci z łańcucha może być gdzieś ważnym przypadkiem użycia, ale nigdy nie musiałem tego robić. Nie chodzi o to, że coś jest nie tak z chęcią pochwalenia się tym, co wiesz - jaki sens mają rzeczy, jeśli nie możesz tego zrobić. :) Jednak argument za istotnością pytania jest zawyżony.
John Lockwood,
1
Jasne, konkretny przykład wybierania alternatywnych znaków może nie być odpowiedni do pytania, ale zrozumienie, że istnieje trzeci parametr bardzo znacznego krojenia jest istotny, a proste przykłady służą do zilustrowania, jak to działa. Społeczność Python ma również wspaniałą historię edukowania nowych członków w przyjazny sposób :-)
Endophage
127

Substr () normalnie (tj. PHP i Perl) działa w ten sposób:

s = Substr(s, beginning, LENGTH)

Więc parametry to beginningi LENGTH.

Ale zachowanie Pythona jest inne; oczekuje początku i jednego po END (!). Jest to trudne do zauważenia przez początkujących. Tak więc poprawnym zamiennikiem dla Substr (s, begin, LENGTH) jest

s = s[ beginning : beginning + LENGTH]
Michał Leon
źródło
75
Początkujący powinni nauczyć się pythonicznego sposobu przechodzenia na python, a nie trzymać się innych nawyków językowych
Nicu Surdu
3
I tylko dla kompletności, Java jest jak Python, ponieważ metoda String.substring () przyjmuje początek i jeden koniec. Ten mocno mnie ugryzł, zakładałem, że ma długość jak każda inna funkcja substring na świecie.
PhilHibbs,
4
(Prawdopodobnie) bardziej pytonicznym sposobem na to jests[beginning:][:length]
victortv
2
Jako ktoś, kto zaczynał od Pythona zamiast [brudnych słów] - języków takich jak PHP, myślę, że Python jest znacznie prostszy i intuicyjny dzięki swoim ciągom znaków [początek: koniec]. Długość zasadniczo nie ma znaczenia.
Gloweye,
60

Częstym sposobem na osiągnięcie tego jest krojenie sznurka.

MyString[a:b] daje ci podciąg od indeksu od a do (b - 1).

naukowiec
źródło
23

Wydaje się, że brakuje tutaj jednego przykładu: pełna (płytka) kopia.

>>> x = "Hello World!"
>>> x
'Hello World!'
>>> x[:]
'Hello World!'
>>> x==x[:]
True
>>>

Jest to wspólny idiom do tworzenia kopii typów sekwencyjnych (nie z internowanych strun) [:]. Płytkie kopie listy, zobacz Składnia wycinka listy Python używana bez wyraźnego powodu .

gimel
źródło
12
Nie ma to prawie nic wspólnego z pytaniem o substring. Nie dotyczy nawet łańcucha. Powiedzenie stringA = stringB wystarczy ...
Nicu Surdu
2
Pełna kopia [:] tworzy NOWĄ KOPIĘ, używa składni plastra i jest czytana jako „podciąg od początku do końca”
gimel
2
Jaki jest sens, ponieważ ciągi są niezmienne? a=bpowinno wystarczyć.
bfontaine
1
@gimel: W rzeczywistości [:]na niezmiennym typie wcale nie robi się kopii. Choć mysequence[:]jest przeważnie nieszkodliwe, gdy mysequencejest niezmienna typu jak str, tuple, bytes(Py3) lub unicode(Py2) a = b[:]jest równoważne a = b, to po prostu traci trochę czasu wysyłki krojenie kodów bajtowych którym reaguje obiektów do wracając się, ponieważ jest to bezcelowe płytkiej kopii gdy , oprócz testów tożsamości obiektu, jest to równoważne po prostu zwrócenie kolejnego odniesienia do niezmiennego ja.
ShadowRanger
3
Próbując podsumować inne krytykę tej odpowiedzi: W Pythonie ciągi są niezmienne, więc nie ma powodu, aby zrobić kopię łańcucha - więc s[:]nie zrobić kopię na wszystko: s = 'abc'; s0 = s[:]; assert s is s0. Tak, to był idiomatyczny sposób kopiowania listy w Pythonie, dopóki listy się list.copynie pojawią, ale pełny kawałek niezmiennego typu nie ma powodu, aby kopiować, ponieważ nie można go zmienić, więc może być tylko jedna pamięć i nie powinniśmy tracić czasu na kopiowanie. Ponieważ ta odpowiedź jest błędna i nawet nie odpowiada na pytanie - czy należy ją usunąć?
Aaron Hall
18

Czy istnieje sposób na podciąganie napisu w Pythonie, aby uzyskać nowy ciąg od 3 znaku do końca ciągu?

Może jak myString[2:end]?

Tak, to faktycznie działa, jeśli przypisujesz lub wiążesz nazwę end, do stałego singletonu None:

>>> end = None
>>> myString = '1234567890'
>>> myString[2:end]
'34567890'

Notacja wycinka zawiera 3 ważne argumenty:

  • początek
  • zatrzymać
  • krok

Ich wartości domyślne, gdy nie są podane, to None- ale możemy je przekazać jawnie:

>>> stop = step = None
>>> start = 2
>>> myString[start:stop:step]
'34567890'

Jeśli opuszczenie drugiej części oznacza „do końca”, jeśli opuścisz pierwszą część, to czy zacznie się od początku?

Tak, na przykład:

>>> start = None
>>> stop = 2
>>> myString[start:stop:step]
'12'

Zauważ, że uwzględniamy start w wycinku, ale wchodzimy tylko do zatrzymania, ale nie wyłączamy go.

Gdy krok jest None, domyślnie plasterek używa 1kroku. Jeśli zrobisz krok z ujemną liczbą całkowitą, Python jest wystarczająco inteligentny, aby przejść od końca do początku.

>>> myString[::-1]
'0987654321'

Objaśniam notację plastra bardzo szczegółowo w mojej odpowiedzi na wyjaśnienie notacji plastra Pytanie.

Aaron Hall
źródło
8

Masz to tutaj, z wyjątkiem „końca”. To się nazywa notacja plastra. Twój przykład powinien brzmieć:

new_sub_string = myString[2:]

Jeśli pominiesz drugi parametr, będzie to domyślnie koniec łańcucha.

bulwar
źródło
6

Chciałbym dodać do dyskusji dwa punkty:

  1. Zamiast tego możesz użyć Nonepustego miejsca, aby określić „od początku” lub „do końca”:

    'abcde'[2:None] == 'abcde'[2:] == 'cde'

    Jest to szczególnie przydatne w funkcjach, w których nie można podać pustej przestrzeni jako argumentu:

    def substring(s, start, end):
        """Remove `start` characters from the beginning and `end` 
        characters from the end of string `s`.
    
        Examples
        --------
        >>> substring('abcde', 0, 3)
        'abc'
        >>> substring('abcde', 1, None)
        'bcde'
        """
        return s[start:end]
  2. Python ma obiekty plasterków :

    idx = slice(2, None)
    'abcde'[idx] == 'abcde'[2:] == 'cde'
ostrokach
źródło
6

Jeśli myString zawiera numer konta, który zaczyna się na przesunięcie 6 i ma długość 9, a następnie można wyodrębnić numer konta w ten sposób: acct = myString[6:][:9].

Jeśli PO zaakceptuje to, mogą chcieć spróbować, eksperymentalnie,

myString[2:][:999999]

Działa - nie pojawia się żaden błąd i nie występuje domyślne „dopełnianie łańcucha”.

CopyPasteIt
źródło
1
Myślę, że jeśli chcesz użyć tej metody myString[offset:][:length]w przypadku OP, możesz po prostu użyćmyString[offset:][:]
victortv
1
@VictorVal Odpowiedź jest dla tych (jak ja), którzy nauczyli się Pythona jako drugiego (trzeciego, czwartego, ...) języka programowania i chcą znajomych „haków składniowych”, aby zbliżyć się do tego języka. Każdy ekspert w języku najprawdopodobniej uzna moją odpowiedź za trochę głupią.
CopyPasteIt
Czy takie odpowiedzi powinny zostać oznaczone do usunięcia? Inne odpowiedzi znacznie lepiej wyjaśniają podobne rozwiązanie, a widok tego jednego zmusił mnie do podrapania się w głowę i odszukania pytona przez kilka minut, zanim zdałem sobie sprawę, że to tylko taka odpowiedź.
Sebi
3

Może mi tego brakowało, ale nie mogłem znaleźć pełnej odpowiedzi na tej stronie na pierwotne pytanie, ponieważ zmienne nie są tutaj omawiane dalej. Musiałem więc dalej szukać.

Ponieważ nie mogę jeszcze komentować, dodam tutaj moją konkluzję. Jestem pewien, że nie byłem tym zainteresowany, gdy wchodziłem na tę stronę:

 >>>myString = 'Hello World'
 >>>end = 5

 >>>myString[2:end]
 'llo'

Jeśli opuścisz pierwszą część, dostaniesz

 >>>myString[:end]
 'Hello' 

A jeśli zostawiłeś: w środku również masz najprostszy podłańcuch, którym byłby piąty znak (policz od 0, więc w tym przypadku jest pusty):

 >>>myString[end]
 ' '
Rudi Uhl
źródło
1

Cóż, dostałem sytuację, w której musiałem przetłumaczyć skrypt PHP na Python i miał wiele zastosowań substr(string, beginning, LENGTH).
Gdybym wybrał Pythona, string[beginning:end]musiałbym obliczyć wiele indeksów końcowych, więc łatwiejszym sposobem było użycie string[beginning:][:length], to zaoszczędziło mi wielu kłopotów.

Edson Horacio Junior
źródło
0

Korzystanie z samych indeksów na stałe może być bałaganem.

Aby tego uniknąć, Python oferuje wbudowany obiekt slice().

string = "my company has 1000$ on profit, but I lost 500$ gambling."

Jeśli chcemy wiedzieć, ile pieniędzy mi zostało.

Normalne rozwiązanie:

final = int(string[15:19]) - int(string[43:46])
print(final)
>>>500

Używanie plasterków:

EARNINGS = slice(15, 19)
LOSSES = slice(43, 46)
final = int(string[EARNINGS]) - int(string[LOSSES])
print(final)
>>>500

Używając wycinka zyskujesz czytelność.

Levi
źródło
5
Może nie jest to najlepszy przykład, ponieważ indeksy zakodowane na stałe pozostają, a czytelność pochodzi ze zmiennych pośrednich, które można było zastosować w pierwszym przykładzie.
ASalazar