Comment obtenir une sous-chaîne d'une chaîne en Python?

2145

Existe-t-il un moyen de sous-chaîne d'une chaîne en Python, pour obtenir une nouvelle chaîne du troisième caractère à la fin de la chaîne?

Peut-être comme myString[2:end]?

Si quitter la deuxième partie signifie «jusqu'à la fin», et si vous quittez la première partie, cela commence-t-il depuis le début?

Joan Venge
la source
1
Celui-ci contient une explication claire pythoncentral.io/cutting-and-slicing-strings-in-python
mario ruiz

Réponses:

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

Python appelle ce concept "slicing" et il fonctionne sur plus que des chaînes. Jetez un œil ici pour une introduction complète.

Paolo Bergantino
la source
401

Juste pour être complet car personne d'autre ne l'a mentionné. Le troisième paramètre d'une tranche de tableau est une étape. Donc, inverser une chaîne est aussi simple que:

some_string[::-1]

Ou sélectionner des caractères alternatifs serait:

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

La possibilité d'avancer et de reculer dans la chaîne maintient la cohérence avec la possibilité de créer une tranche de tableau depuis le début ou la fin.

Endophage
la source
21
@mtahmed absolument lié à la question. Et si vous vouliez créer une sous-chaîne en sélectionnant des caractères alternatifs dans la chaîne? Ce serait my_string [:: 2]
Endophage
Je pense qu'il est plus probable que vous vouliez mentionner le troisième paramètre à découper. Besoin d'obtenir tous les autres caractères d'une chaîne peut être un cas d'utilisation important quelque part, mais je n'ai jamais eu à le faire. Non pas qu'il y ait quelque chose de mal à vouloir montrer ce que vous savez - quel est l'intérêt de savoir les choses si vous ne pouvez pas faire cela. :) Mais l'argument de la pertinence de la question est surestimé.
John Lockwood
1
Bien sûr, l'exemple spécifique de sélection de caractères alternatifs peut ne pas être pertinent pour la question, mais comprendre qu'il existe un troisième paramètre à trancher est pertinent et les exemples simples servent à illustrer comment cela fonctionne. La communauté Python a également une grande histoire d'éduquer les nouveaux membres de manière amicale :-)
Endophage
127

Substr () fonctionne normalement (ie PHP et Perl) de cette façon:

s = Substr(s, beginning, LENGTH)

Les paramètres sont donc beginninget LENGTH.

Mais le comportement de Python est différent; il attend le début et un après la FIN (!). C'est difficile à repérer par les débutants. Donc, le remplacement correct pour Substr (s, début, LONGUEUR) est

s = s[ beginning : beginning + LENGTH]
Michał Leon
la source
76
Les débutants devraient apprendre la voie pythonique lors du passage au python, ne pas s'en tenir à d'autres habitudes linguistiques
Nicu Surdu
3
Et juste pour être complet, Java est comme Python dans la mesure où la méthode String.substring () prend le début et la fin d'un passage. Celui-ci m'a juste mordu fort, j'avais supposé que c'était la longueur comme toutes les autres fonctions de sous-chaîne dans le monde.
PhilHibbs
4
Une façon (probablement) plus pythonique de le faire ests[beginning:][:length]
victortv
2
En tant que personne qui a commencé avec Python au lieu de [mots sales] -langues comme PHP, je pense que Python est beaucoup plus simple et intuitif avec sa chaîne [début: fin]. La longueur n'est généralement pas pertinente.
Gloweye
60

Un moyen courant d'y parvenir est de couper les chaînes.

MyString[a:b] vous donne une sous-chaîne de l'index a à (b - 1).

codingcientist
la source
23

Un exemple semble manquer ici: copie complète (peu profonde).

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

C'est un idiome commun pour créer une copie des types de séquence (pas de chaînes internées), [:]. Shallow copie une liste, voir Syntaxe de tranche de liste Python utilisée sans raison évidente .

gimel
la source
12
Cela n'a presque rien à voir avec la question de la sous-chaîne. Ne s'applique même pas à la chaîne. Dire stringA = stringB suffit ...
Nicu Surdu
2
La copie complète [:] crée une NOUVELLE COPIE, utilise la syntaxe de tranche et est lue comme "une sous-chaîne du début à la fin"
gimel
2
Quel est le point puisque les chaînes sont immuables? a=bdevrait être suffisant.
bfontaine
1
@gimel: En fait, [:]sur un type immuable ne fait pas du tout de copie. Bien que mysequence[:]est la plupart du temps inoffensifs quand mysequenceest un type immuable comme str, tuple, bytes(AP3) ou unicode(AP2), a = b[:]est équivalent à a = b, il gaspille un peu de temps l' envoi des codes d'octets de découpage qui les répond objet par lui - même de retour , car il est inutile de copie peu profonde quand , à part les tests d'identité d'objet, cela revient à simplement renvoyer une autre référence à son soi immuable.
ShadowRanger
3
Toute tentative de résumer les autres critiques de cette réponse: En Python, les chaînes sont immuables, donc il n'y a aucune raison de faire une copie d'une chaîne - donc s[:]ne fait pas une copie du tout: s = 'abc'; s0 = s[:]; assert s is s0. Oui, c'était la façon idiomatique de copier une liste en Python jusqu'à ce que les listes soient obtenues list.copy, mais une tranche complète d'un type immuable n'a aucune raison de faire une copie car elle ne peut pas être modifiée, il peut donc aussi bien y en avoir qu'une seule en mémoire et nous ne devrions pas perdre de temps à le copier. Puisque cette réponse est fausse et ne répond même pas à la question - devrait-elle être supprimée?
Aaron Hall
18

Existe-t-il un moyen de sous-chaîne d'une chaîne en Python, pour obtenir une nouvelle chaîne du 3ème caractère à la fin de la chaîne?

Peut-être comme myString[2:end]?

Oui, cela fonctionne en fait , si vous attribuez, ou se lier , le nom, endà singleton constante, None:

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

La notation de tranche a 3 arguments importants:

  • début
  • Arrêtez
  • étape

Leurs valeurs par défaut lorsqu'elles ne sont pas données sont None- mais nous pouvons les transmettre explicitement:

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

Si quitter la deuxième partie signifie «jusqu'à la fin», si vous quittez la première partie, cela commence-t-il depuis le début?

Oui, par exemple:

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

Notez que nous incluons start dans la tranche, mais nous n'allons que jusqu'à, et non compris, stop.

Lorsque l'étape est None, par défaut, la tranche utilise 1pour l'étape. Si vous marchez avec un entier négatif, Python est assez intelligent pour aller de la fin au début.

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

J'explique la notation de tranche en détail dans ma réponse à la question Expliquer la notation de tranche.

Aaron Hall
la source
8

Vous l'avez ici, sauf pour "end". C'est ce qu'on appelle la notation de tranche. Votre exemple devrait se lire:

new_sub_string = myString[2:]

Si vous omettez le deuxième paramètre, il s'agit implicitement de la fin de la chaîne.

bouvard
la source
6

Je voudrais ajouter deux points à la discussion:

  1. Vous pouvez utiliser à la Noneplace sur un espace vide pour spécifier "du début" ou "jusqu'à la fin":

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

    Ceci est particulièrement utile dans les fonctions, où vous ne pouvez pas fournir un espace vide comme argument:

    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 a des objets slice :

    idx = slice(2, None)
    'abcde'[idx] == 'abcde'[2:] == 'cde'
ostrokach
la source
6

Si myString contient un numéro de compte qui commence à l' offset 6 et 9 a une longueur, vous pouvez extraire le numéro de compte de cette façon: acct = myString[6:][:9].

Si le PO accepte cela, il pourrait vouloir essayer, de manière expérimentale,

myString[2:][:999999]

Cela fonctionne - aucune erreur n'est déclenchée et aucun «remplissage de chaîne» par défaut ne se produit.

CopyPasteIt
la source
1
Je pense que si vous voulez utiliser cette méthode myString[offset:][:length]dans le cas de l'OP, vous pouvez simplement utilisermyString[offset:][:]
victortv
1
@VictorVal La réponse s'adresse à ceux (comme moi) qui ont appris Python en tant que 2ème (3ème, 4ème, ...) langage de programmation et qui souhaitent utiliser des "crochets de syntaxe" familiers pour aborder le langage. Tout expert dans la langue considérera très probablement ma réponse comme un peu idiote.
CopyPasteIt
Des réponses comme celle-ci doivent-elles être signalées pour suppression? D'autres réponses expliquent beaucoup mieux la solution similaire, et voir celle-ci m'a fait me gratter la tête et chercher du python pendant quelques minutes avant de réaliser que c'est juste ce type de réponse.
Sebi
3

Je l'ai peut-être manqué, mais je n'ai pas trouvé de réponse complète sur cette page aux questions d'origine car les variables ne sont pas discutées plus en détail ici. J'ai donc dû continuer à chercher.

Comme je ne suis pas encore autorisé à commenter, permettez-moi d'ajouter ma conclusion ici. Je suis sûr que je n'étais pas le seul intéressé à y accéder en accédant à cette page:

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

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

Si vous quittez la première partie, vous obtenez

 >>>myString[:end]
 'Hello' 

Et si vous avez laissé le: au milieu également, vous avez la sous-chaîne la plus simple, qui serait le 5ème caractère (comptez en commençant par 0, c'est donc le blanc dans ce cas):

 >>>myString[end]
 ' '
Rudi Uhl
la source
1

Eh bien, j'ai eu une situation où je devais traduire un script PHP en Python, et il avait de nombreuses utilisations de substr(string, beginning, LENGTH).
Si je choisissais Python, string[beginning:end]je devrais calculer beaucoup d'index de fin, donc la façon la plus simple était d'utiliser string[beginning:][:length], cela m'a sauvé beaucoup de problèmes.

Edson Horacio Junior
la source
0

L'utilisation d'index codés en dur peut être un gâchis.

Afin d'éviter cela, Python propose un objet intégré slice().

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

Si nous voulons savoir combien d'argent il me reste.

Solution normale:

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

Utilisation de tranches:

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

En utilisant la tranche, vous gagnez en lisibilité.

levi
la source
5
Ce n'est peut-être pas le meilleur exemple, car les index codés en dur restent et la lisibilité provient de variables intermédiaires, que vous auriez pu utiliser dans le premier exemple.
ASalazar