Question

J'ai besoin d'une bonne explication (les références sont un plus) sur la notation slice de Python.

Pour moi, cette notation a besoin d’être un peu reprise.

Cela a l’air extrêmement puissant, mais je n’ai pas encore bien compris.

Était-ce utile?

La solution

Il est vraiment très simple:

a[start:stop]  # items start through stop-1
a[start:]      # items start through the rest of the array
a[:stop]       # items from the beginning through stop-1
a[:]           # a copy of the whole array

Il y a aussi la valeur step, qui peut être utilisé avec tout de ce qui précède:

a[start:stop:step] # start through not past stop, by step

Le point essentiel à retenir est que la valeur représente la :stop première valeur qui est pas dans la tranche sélectionnée. Ainsi, la différence entre stop et start est le nombre d'éléments sélectionné (si a[:-2] est égal à 1, la valeur par défaut).

L'autre caractéristique est que ou a peut être un slice() négatif nombre, ce qui signifie qu'il compte à partir de la fin du tableau au lieu du début. Donc:

a[-1]    # last item in the array
a[-2:]   # last two items in the array
a[:-2]   # everything except the last two items

De même, peut être un [] nombre négatif:

a[::-1]    # all items in the array, reversed
a[1::-1]   # the first two items, reversed
a[:-3:-1]  # the last two items, reversed
a[-3::-1]  # everything except the last two items, reversed

Python est bon pour le programmeur s'il y a moins d'éléments que vous demandez. Par exemple, si vous demandez et : range() ne contient un élément, vous obtenez une liste vide au lieu d'une erreur. Parfois, vous préférez l'erreur, alors vous devez savoir que cela peut se produire.

Relation à l'objet slice(stop)

L'opérateur de tranchage slice(start, stop[, step]) est effectivement utilisé dans le code ci-dessus avec un objet en utilisant la notation None a[start:] (qui est seulement valide dans a[slice(start, None)]), i.e.:.

a[start:stop:step]

est équivalent à:

a[slice(start, stop, step)]

tranche des objets se comportent légèrement différemment selon le nombre d'arguments, de façon similaire à a[::-1], à savoir à la fois et a[slice(None, None, -1)] sont pris en charge <=>. Pour ignorer la spécification d'un argument donné, on peut utiliser <=>, de sorte que par exemple <=> est équivalente à <=> ou <=> est équivalent à <=>.

Alors que <=> -. Notation à base est très utile pour trancher simple, l'utilisation explicite des objets simplifie la <=> génération programmatique de découpage en tranches

Autres conseils

Python tutoriel en parle (défiler vers le bas un peu jusqu'à ce que vous obtenez pour la partie concernant le découpage).

Le diagramme d'art ASCII est trop utile pour se rappeler comment fonctionnent les tranches:

 +---+---+---+---+---+---+
 | P | y | t | h | o | n |
 +---+---+---+---+---+---+
 0   1   2   3   4   5   6
-6  -5  -4  -3  -2  -1
  

Une façon de se rappeler comment le travail des tranches est de penser des indices comme pointant vers entre caractères, avec le bord gauche du premier caractère de rang 0. Ensuite, le bord droit du dernier caractère d'une chaîne de n caractères a l'index n .

Énumérer les possibilités permises par la grammaire:

>>> seq[:]                # [seq[0],   seq[1],          ..., seq[-1]    ]
>>> seq[low:]             # [seq[low], seq[low+1],      ..., seq[-1]    ]
>>> seq[:high]            # [seq[0],   seq[1],          ..., seq[high-1]]
>>> seq[low:high]         # [seq[low], seq[low+1],      ..., seq[high-1]]
>>> seq[::stride]         # [seq[0],   seq[stride],     ..., seq[-1]    ]
>>> seq[low::stride]      # [seq[low], seq[low+stride], ..., seq[-1]    ]
>>> seq[:high:stride]     # [seq[0],   seq[stride],     ..., seq[high-1]]
>>> seq[low:high:stride]  # [seq[low], seq[low+stride], ..., seq[high-1]]

Bien sûr, si (high-low)%stride != 0, le point final sera un peu inférieur à high-1.

Si est négatif stride, l'ordre est un peu changé puisque nous décompter:

>>> seq[::-stride]        # [seq[-1],   seq[-1-stride],   ..., seq[0]    ]
>>> seq[high::-stride]    # [seq[high], seq[high-stride], ..., seq[0]    ]
>>> seq[:low:-stride]     # [seq[-1],   seq[-1-stride],   ..., seq[low+1]]
>>> seq[high:low:-stride] # [seq[high], seq[high-stride], ..., seq[low+1]]

tranchage de longue durée (par des virgules et des ellipses) sont principalement utilisés que par les structures de données particulières (comme NumPy); les séquences de base ne les supportent pas.

>>> class slicee:
...     def __getitem__(self, item):
...         return repr(item)
...
>>> slicee()[0, 1:2, ::5, ...]
'(0, slice(1, 2, None), slice(None, None, 5), Ellipsis)'

Les réponses ci-dessus ne discutent pas de l'affectation de tranche. Pour comprendre l'affectation de tranche, il est utile d'ajouter un autre concept à l'art ASCII:

                +---+---+---+---+---+---+
                | P | y | t | h | o | n |
                +---+---+---+---+---+---+
Slice position: 0   1   2   3   4   5   6
Index position:   0   1   2   3   4   5

>>> p = ['P','y','t','h','o','n']
# Why the two sets of numbers:
# indexing gives items, not lists
>>> p[0]
 'P'
>>> p[5]
 'n'

# Slicing gives lists
>>> p[0:1]
 ['P']
>>> p[0:2]
 ['P','y']

Une heuristique est, pour une tranche de zéro à n, pense. « Zéro est le début, commencez au début et à prendre des éléments n dans une liste »

>>> p[5] # the last of six items, indexed from zero
 'n'
>>> p[0:5] # does NOT include the last item!
 ['P','y','t','h','o']
>>> p[0:6] # not p[0:5]!!!
 ['P','y','t','h','o','n']

Une autre heuristique est, « pour toute tranche, remplacer le début par zéro, appliquer l'heuristique précédente pour obtenir la fin de la liste, puis compter le premier numéro de secours pour couper les éléments hors début »

>>> p[0:4] # Start at the beginning and count out 4 items
 ['P','y','t','h']
>>> p[1:4] # Take one item off the front
 ['y','t','h']
>>> p[2:4] # Take two items off the front
 ['t','h']
# etc.

La première règle d'affectation de tranche est que depuis tranchage retourne une liste, l'affectation de tranche nécessite une liste (ou autre itérables):

>>> p[2:3]
 ['t']
>>> p[2:3] = ['T']
>>> p
 ['P','y','T','h','o','n']
>>> p[2:3] = 't'
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: can only assign an iterable

La deuxième règle d'affectation de tranche, que vous pouvez également voir ci-dessus, est que quelle que soit la partie de la liste est renvoyée par l'indexation des tranches, qui est la même partie qui est modifiée par l'affectation de tranche:

>>> p[2:4]
 ['T','h']
>>> p[2:4] = ['t','r']
>>> p
 ['P','y','t','r','o','n']

La troisième règle d'affectation de tranche est, la liste assignée (itérables) ne doit pas avoir la même longueur; la tranche indexée est simplement découpé et remplacé en masse par tout ce qui est attribué:

>>> p = ['P','y','t','h','o','n'] # Start over
>>> p[2:4] = ['s','p','a','m']
>>> p
 ['P','y','s','p','a','m','o','n']

La partie la plus délicate à se habituer à l'affectation est de vider les tranches. L'utilisation heuristique 1 et 2, il est facile d'obtenir autour de votre tête indexation une tranche vide:

>>> p = ['P','y','t','h','o','n']
>>> p[0:4]
 ['P','y','t','h']
>>> p[1:4]
 ['y','t','h']
>>> p[2:4]
 ['t','h']
>>> p[3:4]
 ['h']
>>> p[4:4]
 []

Et puis une fois que vous avez vu que, l'affectation de tranche à la tranche vide est logique aussi:

>>> p = ['P','y','t','h','o','n']
>>> p[2:4] = ['x','y'] # Assigned list is same length as slice
>>> p
 ['P','y','x','y','o','n'] # Result is same length
>>> p = ['P','y','t','h','o','n']
>>> p[3:4] = ['x','y'] # Assigned list is longer than slice
>>> p
 ['P','y','t','x','y','o','n'] # The result is longer
>>> p = ['P','y','t','h','o','n']
>>> p[4:4] = ['x','y']
>>> p
 ['P','y','t','h','x','y','o','n'] # The result is longer still

Notez que, puisque nous ne changeons pas le deuxième numéro de la tranche (4), les éléments insérés pile toujours tout contre le « o », même quand nous attribuons à la tranche vide. Ainsi, la position de l'affectation de la tranche vide est l'extension logique des positions pour les affectations de tranche non vides.

Sauvegarde un peu, ce qui se passe lorsque vous continuez à aller avec notre procession de compter jusqu'à la tranche commençant?

>>> p = ['P','y','t','h','o','n']
>>> p[0:4]
 ['P','y','t','h']
>>> p[1:4]
 ['y','t','h']
>>> p[2:4]
 ['t','h']
>>> p[3:4]
 ['h']
>>> p[4:4]
 []
>>> p[5:4]
 []
>>> p[6:4]
 []

Slicing, une fois que vous avez terminé, vous avez terminé; il ne démarre pas trancher en arrière. En Python, vous ne recevez pas des progrès négatifs sauf si vous demandez explicitement pour eux en utilisant un nombre négatif.

>>> p[5:3:-1]
 ['n','o']

Il y a des conséquences étranges à la « une fois que vous avez terminé, vous avez terminé » règle:

>>> p[4:4]
 []
>>> p[5:4]
 []
>>> p[6:4]
 []
>>> p[6]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
IndexError: list index out of range

En fait, par rapport à l'indexation, le découpage Python est l'épreuve d'baroquement erreur:

>>> p[100:200]
 []
>>> p[int(2e99):int(1e99)]
 []

Cela peut être utile parfois, mais il peut aussi conduire à un comportement un peu étrange:

>>> p
 ['P', 'y', 't', 'h', 'o', 'n']
>>> p[int(2e99):int(1e99)] = ['p','o','w','e','r']
>>> p
 ['P', 'y', 't', 'h', 'o', 'n', 'p', 'o', 'w', 'e', 'r']

En fonction de votre application, qui pourrait ... ou peut-être pas ... être ce que vous espériez là!


Voici le texte de ma réponse initiale. Il a été utile pour beaucoup de gens, donc je ne voulais pas le supprimer.

>>> r=[1,2,3,4]
>>> r[1:1]
[]
>>> r[1:1]=[9,8]
>>> r
[1, 9, 8, 2, 3, 4]
>>> r[1:1]=['blah']
>>> r
[1, 'blah', 9, 8, 2, 3, 4]

Cela peut également préciser la différence entre le découpage et l'indexation.

  

Expliquer la notation de la tranche de Python

En bref, les points (en notation) : indice (subscriptable[subscriptarg]) faire de la notation tranche - qui a les arguments optionnels, start stop, step:

sliceable[start:stop:step]

découpage en tranches Python est un moyen rapide d'accéder informatiquement méthodiquement les parties de vos données. À mon avis, d'être même un programmeur Python intermédiaire, il est un aspect de la langue qu'il est nécessaire de se familiariser avec.

Définitions importantes

Pour commencer, nous allons définir quelques termes:

  

start: l'indice au début de la tranche, il comprendra l'élément à cet indice à moins qu'il soit le même que arrêter , par défaut à 0, à savoir le premier indice . Si elle est négative, cela signifie que pour commencer des éléments de la n fin.

     

arrêt: l'index de fin de la tranche, Finalité pas comprennent l'élément à cet indice, par défaut à la longueur de la séquence en cours de tranchées, qui est, jusqu'à et comprenant l'extrémité.

     

Étape:. le montant par lequel l'indice augmente, par défaut 1. Si elle est négative, vous êtes trancher sur itérable en sens inverse

Comment fonctionne l'indexation

Vous pouvez faire l'un de ces nombres positifs ou négatifs. La signification des nombres positifs est simple, mais pour les nombres négatifs, tout comme les index en Python, vous compter à rebours de la fin pour la start et arrêter , et pour la < em> pas , vous décrémentez simplement votre index. Cet exemple est de tutoriel de la documentation, mais je l'ai modifié légèrement pour indiquer quel élément dans une séquence d'index chacune des références:

 +---+---+---+---+---+---+
 | P | y | t | h | o | n |
 +---+---+---+---+---+---+
   0   1   2   3   4   5 
  -6  -5  -4  -3  -2  -1

Comment fonctionne Slicing

Pour utiliser la notation tranche avec une séquence qui prend en charge, vous devez inclure au moins un colon dans les crochets qui suivent la séquence (qui en fait mettre en oeuvre le procédé __getitem__ de la séquence, selon le modèle de données de python .)

notation tranche fonctionne comme ceci:

sequence[start:stop:step]

Et rappellent qu'il ya des valeurs par défaut pour start , Arrêter et pas , pour ainsi accéder aux valeurs par défaut, laissez simplement l'argument.

notation tranche pour obtenir les neuf derniers éléments d'une liste (ou toute autre séquence qui prend en charge, comme une chaîne) ressemblerait à ceci:

my_list[-9:]

Quand je vois cela, je lis la partie entre crochets comme « 9 de la fin, jusqu'à la fin. » (En fait, j'abrège mentalement comme "-9, sur")

Explication:

La notation complète est

my_list[-9:None:None]

et de remplacer les valeurs par défaut (en fait quand est par défaut -len(my_list) - 1 de «négative, est None list.copy, donc pour vraiment arrêter list.clear signifie simplement qu'il va selon l'étape de fin, il faut pour):

my_list[-9:len(my_list):1]

côlon , +1, est ce qui dit Python que vous donnez une tranche et non un indice régulier. Voilà pourquoi la façon idiomatiques de faire une copie superficielle des listes en Python 2 est

list_copy = sequence[:]

Et les effacer est avec:

del my_list[:]

(Python 3 obtient un procédé -1 et list.__getitem__.)

Quand est négatif itertools.islice, les valeurs par défaut et islice changement <=>

Par défaut, quand l'argument <=> est vide (ou <=>), il est assigné à <=>.

Mais vous pouvez passer dans un entier négatif, et la liste (ou la plupart des autres slicables standard) sera coupé en tranches de la fin au début.

Ainsi, une tranche négative va changer les valeurs par défaut pour et <=> <=>!

Confirmant ceci dans la source

J'aime encourager les utilisateurs à lire la source ainsi que la documentation. pour les objets de tranche et cette logique se trouve ici . D'abord, nous déterminons si négatif est <=>:

 step_is_negative = step_sign < 0;

Dans ce cas, la limite est inférieure <=> qui signifie que nous découpons tout le chemin jusqu'à unnd y compris le début et la limite supérieure est la longueur moins 1, ce qui signifie que nous commençons à la fin. (Notez que la sémantique de c'est <=> différents à partir d'un que les utilisateurs peuvent <=> passer des index en Python indiquant le dernier élément.)

if (step_is_negative) {
    lower = PyLong_FromLong(-1L);
    if (lower == NULL)
        goto error;

    upper = PyNumber_Add(length, lower);
    if (upper == NULL)
        goto error;
}

Dans le cas contraire est positif <=>, et la limite inférieure est égale à zéro et la limite supérieure (que nous montons mais non compris) la longueur de la liste en tranches.

else {
    lower = _PyLong_Zero;
    Py_INCREF(lower);
    upper = length;
    Py_INCREF(upper);
}

Ensuite, nous devons appliquer les valeurs par défaut pour et <=> <=> - la valeur par défaut alors pour est calculée comme <=> la limite supérieure est négatif lorsque <=>:

if (self->start == Py_None) {
    start = step_is_negative ? upper : lower;
    Py_INCREF(start);
}

et <=>, la borne inférieure:

if (self->stop == Py_None) {
    stop = step_is_negative ? lower : upper;
    Py_INCREF(stop);
}

Donnez à vos tranches un nom descriptif!

Vous trouverez peut-être utile de séparer la formation de la tranche de celui-ci passant à la méthode <=> ( c'est ce que les crochets font ). Même si vous n'êtes pas à nouveau, il maintient votre code plus lisible pour que les autres qui peuvent avoir à lire votre code peut comprendre plus facilement ce que vous faites.

Cependant, vous ne pouvez pas attribuer des entiers séparés par des virgules à une variable. Vous devez utiliser l'objet tranche:

last_nine_slice = slice(-9, None)

Le second argument, <=>, est nécessaire, de sorte que le premier argument est interprété comme argument <=> sinon ce serait l'argument <=>.

Vous pouvez ensuite passer l'objet de tranche à votre séquence:

>>> list(range(100))[last_nine_slice]
[91, 92, 93, 94, 95, 96, 97, 98, 99]

Il est intéressant qui va aussi prendre des tranches:

>>> range(100)[last_nine_slice]
range(91, 100)

Considérations sur la mémoire:

Depuis des tranches de listes Python créer de nouveaux objets dans la mémoire, une autre fonction importante à prendre en compte est <=>. En général, vous aurez envie d'itérer sur une tranche, pas juste créé statiquement dans la mémoire. Est parfait pour <=> cela. Une mise en garde, il ne supporte pas les arguments négatifs à <=>, <=> ou <=>, donc si c'est une question que vous devrez peut-être calculer des indices ou inverser la itérables à l'avance.

length = 100
last_nine_iter = itertools.islice(list(range(length)), length-9, None, 1)
list_last_nine = list(last_nine_iter)

et maintenant:

>>> list_last_nine
[91, 92, 93, 94, 95, 96, 97, 98, 99]

Le fait que les tranches de liste font une copie est une caractéristique des listes elles-mêmes. Si vous couper des objets avancés comme un Pandas dataframe, il peut renvoyer une vue sur l'original, et non une copie.

Et une ou deux choses qui ne sont pas immédiatement évident pour moi quand je l'ai vu la syntaxe de coupe:

>>> x = [1,2,3,4,5,6]
>>> x[::-1]
[6,5,4,3,2,1]

Un moyen facile d'inverser les séquences!

Et si vous voulez, pour une raison quelconque, chaque deuxième élément de la séquence inversée:

>>> x = [1,2,3,4,5,6]
>>> x[::-2]
[6,4,2]

En Python 2.7

Trancheuse dans le python

[a:b:c]

len = length of string, tuple or list

c -- default is +1. The sign of c indicates forward or backward, absolute value of c indicates steps. Default is forward with step size 1. Positive means forward, negative means backward.

a --  When c is positive or blank, default is 0. When c is negative, default is -1.

b --  When c is positive or blank, default is len. When c is negative, default is -(len+1).

Affectation index La compréhension est très important.

In forward direction, starts at 0 and ends at len-1

In backward direction, starts at -1 and ends at -len

Quand vous dites [a: b: c], vous dites en fonction du signe de c (avant ou arrière), commencez à une extrémité et à b (hors élément à l'index de BTH). Utilisez la règle d'indexation ci-dessus et sachez que vous ne trouverez des éléments de cette gamme:

-len, -len+1, -len+2, ..., 0, 1, 2,3,4 , len -1

Mais cette gamme continue infiniment dans les deux sens:

...,-len -2 ,-len-1,-len, -len+1, -len+2, ..., 0, 1, 2,3,4 , len -1, len, len +1, len+2 , ....

Par exemple:

             0    1    2   3    4   5   6   7   8   9   10   11
             a    s    t   r    i   n   g
    -9  -8  -7   -6   -5  -4   -3  -2  -1

Si votre choix a, b, et c permet un chevauchement avec la gamme ci-dessus que vous traversez en utilisant des règles pour a, b, c ci-dessus vous soit obtenir une liste avec des éléments (effleuré lors traversal) ou vous obtiendrez un vide liste.

Une dernière chose: si a et b sont égaux, vous obtenez également une liste vide:

>>> l1
[2, 3, 4]

>>> l1[:]
[2, 3, 4]

>>> l1[::-1] # a default is -1 , b default is -(len+1)
[4, 3, 2]

>>> l1[:-4:-1] # a default is -1
[4, 3, 2]

>>> l1[:-3:-1] # a default is -1
[4, 3]

>>> l1[::] # c default is +1, so a default is 0, b default is len
[2, 3, 4]

>>> l1[::-1] # c is -1 , so a default is -1 and b default is -(len+1)
[4, 3, 2]


>>> l1[-100:-200:-1] # Interesting
[]

>>> l1[-1:-200:-1] # Interesting
[4, 3, 2]


>>> l1[-1:-1:1]
[]


>>> l1[-1:5:1] # Interesting
[4]


>>> l1[1:-7:1]
[]

>>> l1[1:-7:-1] # Interesting
[3, 2]

>>> l1[:-2:-2] # a default is -1, stop(b) at -2 , step(c) by 2 in reverse direction
[4]

J'ai trouvé cette superbe table chez http://wiki.python.org/moin/MovingToPythonFromOtherLanguages

Python indexes and slices for a six-element list.
Indexes enumerate the elements, slices enumerate the spaces between the elements.

Index from rear:    -6  -5  -4  -3  -2  -1      a=[0,1,2,3,4,5]    a[1:]==[1,2,3,4,5]
Index from front:    0   1   2   3   4   5      len(a)==6          a[:5]==[0,1,2,3,4]
                   +---+---+---+---+---+---+    a[0]==0            a[:-2]==[0,1,2,3]
                   | a | b | c | d | e | f |    a[5]==5            a[1:2]==[1]
                   +---+---+---+---+---+---+    a[-1]==5           a[1:-1]==[1,2,3,4]
Slice from front:  :   1   2   3   4   5   :    a[-2]==4
Slice from rear:   :  -5  -4  -3  -2  -1   :
                                                b=a[:]
                                                b==[0,1,2,3,4,5] (shallow copy of a)

Après avoir utilisé un peu je me rends compte que la description la plus simple est que c'est exactement le même que les arguments dans une boucle ... for

(from:to:step)

Chacun d'entre eux sont facultatifs:

(:to:step)
(from::step)
(from:to)

Ensuite, l'indexation négative vous a juste besoin d'ajouter la longueur de la chaîne aux indices négatifs pour le comprendre.

Cela fonctionne pour moi quand même ...

Je trouve plus facile de se rappeler comment cela fonctionne, et je peux comprendre tout marche / arrêt / combinaison étape spécifique.

Il est instructif de comprendre d'abord range():

def range(start=0, stop, step=1):  # Illegal syntax, but that's the effect
    i = start
    while (i < stop if step > 0 else i > stop):
        yield i
        i += step

Début de start, par incrément step, ne pas atteindre stop. Très simple.

La chose à retenir à propos de l'étape négatif est que est toujours la 'abcde'[1:-2][::-1] fin exclue, que ce soit supérieur ou inférieur. Si vous voulez même tranche dans l'ordre inverse, il est beaucoup plus propre à faire séparément l'inversion: par exemple Un large reversed() tranches ombles de gauche, deux de droite, puis renverse. (Voir aussi is None.)

découpage de séquence est le même, sauf que ce premier index négatifs normalise, et il ne peut jamais aller à l'extérieur de la séquence:

TODO : Le code ci-dessous avait un bug avec "jamais aller en dehors de la séquence" quand abs (étape)> 1; I penser Je patché pour être correct, mais il est difficile à comprendre.

def this_is_how_slicing_works(seq, start=None, stop=None, step=1):
    if start is None:
        start = (0 if step > 0 else len(seq)-1)
    elif start < 0:
        start += len(seq)
    if not 0 <= start < len(seq):  # clip if still outside bounds
        start = (0 if step > 0 else len(seq)-1)
    if stop is None:
        stop = (len(seq) if step > 0 else -1)  # really -1, not last element
    elif stop < 0:
        stop += len(seq)
    for i in range(start, stop, step):
        if 0 <= i < len(seq):
            yield seq[i]

Ne vous inquiétez pas les détails 'abcde'[1:-2] == 'abcde'[1:3] == 'bc' -. Rappelez-vous juste que l'omission et range(1,-2) == [] / ou ne toujours 'abcde'[-53:42] bonne chose pour vous donner toute la séquence

La normalisation des indices négatifs permet d'abord démarrer et / ou arrêter à compter de la fin indépendamment: <=> malgré <=>. La normalisation est parfois considérée comme « modulo la longueur », mais notez qu'il ajoute la longueur juste une fois: par exemple Est juste la <=> chaîne entière.

Index:
      ------------>
  0   1   2   3   4
+---+---+---+---+---+
| a | b | c | d | e |
+---+---+---+---+---+
  0  -4  -3  -2  -1
      <------------

Slice:
    <---------------|
|--------------->
:   1   2   3   4   :
+---+---+---+---+---+
| a | b | c | d | e |
+---+---+---+---+---+
:  -4  -3  -2  -1   :
|--------------->
    <---------------|

J'espère que cela vous aidera à modéliser la liste en Python.

Référence: http://wiki.python.org/moin/MovingToPythonFromOtherLanguages

J'utilise le « un point index entre les éléments » méthode de penser à moi-même, mais une façon de décrire ce qui aide parfois d'autres l'obtenir est la suivante:

mylist[X:Y]

X est l'indice du premier élément que vous voulez.
Y est l'indice du premier élément que vous ne pas voulez.

notation de découpage en tranches Python:

a[start:end:step]
  • Pour start et end, les valeurs négatives sont interprétées comme étant par rapport à la fin de la séquence.
  • indices positifs pour indiquer la position [+0:-0:1] après le dernier élément à inclure.
  • Les valeurs vides sont initialisés comme suit:. deepcopy()
  • Utilisation d'un pas négatif inverse l'interprétation de <=> et <=>

La notation se prolonge à matrices (numpy) et de tableaux multidimensionnels. Par exemple, pour couper des colonnes entières, vous pouvez utiliser:

m[::,0:2:] ## slice the first two columns

Les tranches détiennent des références, pas des copies, des éléments du tableau. Si vous souhaitez effectuer une copie distincte un tableau, vous pouvez utiliser <=> .

Vous pouvez également utiliser l'affectation de tranche pour supprimer un ou plusieurs éléments d'une liste:

r = [1, 'blah', 9, 8, 2, 3, 4]
>>> r[1:4] = []
>>> r
[1, 2, 3, 4]

Voici comment j'enseigne tranches à newbies:

Comprendre les différences entre l'indexation et tranchage:

Wiki Python a cette image étonnante qui distingue clairement l'indexation et le découpage.

entrer image description ici

Il est une liste avec 6 éléments en elle. Pour comprendre mieux trancher, considérer cette liste comme un ensemble de six boîtes placés ensemble. Chaque boîte a un alphabet en elle.

L'indexation est comme traiter avec le contenu de la boîte. Vous pouvez vérifier le contenu de toute boîte. Mais vous ne pouvez pas vérifier le contenu de plusieurs boîtes à la fois. Vous pouvez même remplacer le contenu de la boîte. Mais vous ne pouvez pas placer 2 balles dans 1 boîte ou remplacer 2 balles à la fois.

In [122]: alpha = ['a', 'b', 'c', 'd', 'e', 'f']

In [123]: alpha
Out[123]: ['a', 'b', 'c', 'd', 'e', 'f']

In [124]: alpha[0]
Out[124]: 'a'

In [127]: alpha[0] = 'A'

In [128]: alpha
Out[128]: ['A', 'b', 'c', 'd', 'e', 'f']

In [129]: alpha[0,1]
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-129-c7eb16585371> in <module>()
----> 1 alpha[0,1]

TypeError: list indices must be integers, not tuple

Slicing est comme traiter avec des boîtes lui-même. Vous pouvez pickup première boîte et placez-le sur une autre table. Pour intercepter la boîte tout ce qu'il faut savoir est la position de début et de fin de la boîte.

Vous pouvez même pick-up première 3 boîtes ou 2 dernières cases ou toutes les cases entre 1 et 4. Ainsi, vous pouvez choisir un ensemble de boîtes si vous savez commencer et fin. Cette position sont appelées positions de départ et arrêt.

La chose intéressante est que vous pouvez remplacer plusieurs cases à la fois. Aussi, vous pouvez placer plusieurs boîtes où vous le souhaitez.

In [130]: alpha[0:1]
Out[130]: ['A']

In [131]: alpha[0:1] = 'a'

In [132]: alpha
Out[132]: ['a', 'b', 'c', 'd', 'e', 'f']

In [133]: alpha[0:2] = ['A', 'B']

In [134]: alpha
Out[134]: ['A', 'B', 'c', 'd', 'e', 'f']

In [135]: alpha[2:2] = ['x', 'xx']

In [136]: alpha
Out[136]: ['A', 'B', 'x', 'xx', 'c', 'd', 'e', 'f']

Slicing à l'étape:

Jusqu'à présent, vous avez des boîtes cueillies en continu. Mais quelques fois Vous devez pick-up discret. Vous pouvez par exemple pick-up à chaque seconde boîte. Vous pouvez même pick-up chaque troisième case de la fin. Cette valeur est appelée taille de pas. Cela représente l'écart entre vos micros successifs. La taille de l'étape devrait être positive si vous ramassez les boîtes du début à la fin et vice versa.

In [137]: alpha = ['a', 'b', 'c', 'd', 'e', 'f']

In [142]: alpha[1:5:2] 
Out[142]: ['b', 'd']

In [143]: alpha[-1:-5:-2]
Out[143]: ['f', 'd']

In [144]: alpha[1:5:-2]
Out[144]: []

In [145]: alpha[-1:-5:2]      
Out[145]: []

Comment Python devinera Paramètres manquants:

Lors de tranchage si vous laissez un paramètre, Python essaie de comprendre automatiquement.

Si vous vérifiez le code source de CPython, vous trouverez une fonction appelée PySlice_GetIndicesEx qui figure sur les indices d'une tranche pour les paramètres donnés. Voici le code équivalent logique en Python.

Cette fonction prend un objet Python et les paramètres facultatifs pour couper et retours démarrage, arrêt, étape et longueur de tranche pour la tranche demandée.

def py_slice_get_indices_ex(obj, start=None, stop=None, step=None):

    length = len(obj)

    if step is None:
        step = 1
    if step == 0:
        raise Exception("Step cannot be zero.")

    if start is None:
        start = 0 if step > 0 else length - 1
    else:
        if start < 0:
            start += length
        if start < 0:
            start = 0 if step > 0 else -1
        if start >= length:
            start = length if step > 0 else length - 1

    if stop is None:
        stop = length if step > 0 else -1
    else:
        if stop < 0:
            stop += length
        if stop < 0:
            stop = 0 if step > 0 else -1
        if stop >= length:
            stop = length if step > 0 else length - 1

    if (step < 0 and stop >= start) or (step > 0 and start >= stop):
        slice_length = 0
    elif step < 0:
        slice_length = (stop - start + 1)/(step) + 1
    else:
        slice_length = (stop - start - 1)/(step) + 1

    return (start, stop, step, slice_length)

Ceci est l'intelligence qui est présent derrière les tranches. Depuis Python a une fonction appelée tranche intégrée, vous pouvez passer certains paramètres et vérifier comment il calcule intelligemment les paramètres manquants.

In [21]: alpha = ['a', 'b', 'c', 'd', 'e', 'f']

In [22]: s = slice(None, None, None)

In [23]: s
Out[23]: slice(None, None, None)

In [24]: s.indices(len(alpha)) 
Out[24]: (0, 6, 1)

In [25]: range(*s.indices(len(alpha)))
Out[25]: [0, 1, 2, 3, 4, 5]

In [26]: s = slice(None, None, -1) 

In [27]: range(*s.indices(len(alpha)))
Out[27]: [5, 4, 3, 2, 1, 0]

In [28]: s = slice(None, 3, -1)        

In [29]: range(*s.indices(len(alpha)))
Out[29]: [5, 4]

Remarque: Ce poste est à l'origine écrit dans mon blog http://www.avilpage.com/2015/03/a-slice-of-python-intelligence-behind.html

Ceci est juste pour quelques informations supplémentaires ... Tenez compte de la liste ci-dessous

>>> l=[12,23,345,456,67,7,945,467]

Peu d'autres astuces pour inverser la liste:

>>> l[len(l):-len(l)-1:-1]
[467, 945, 7, 67, 456, 345, 23, 12]

>>> l[:-len(l)-1:-1]
[467, 945, 7, 67, 456, 345, 23, 12]

>>> l[len(l)::-1]
[467, 945, 7, 67, 456, 345, 23, 12]

>>> l[::-1]
[467, 945, 7, 67, 456, 345, 23, 12]

>>> l[-1:-len(l)-1:-1]
[467, 945, 7, 67, 456, 345, 23, 12]

En règle générale, le code écrit avec beaucoup de valeurs d'index hardcoded conduit à une lisibilité et le désordre de l'entretien. Par exemple, si vous revenez au code un an plus tard, vous aurez regardez et je me demande ce que vous pensiez quand vous l'avez écrit. La solution représentée est tout simplement une façon de plus en indiquant clairement ce que votre code est en train de faire. En général, la tranche intégrée () crée un objet de tranche qui peut être utilisé partout une tranche est autorisée. Par exemple:

>>> items = [0, 1, 2, 3, 4, 5, 6]
>>> a = slice(2, 4)
>>> items[2:4]
[2, 3]
>>> items[a]
[2, 3]
>>> items[a] = [10,11]
>>> items
[0, 1, 10, 11, 4, 5, 6]
>>> del items[a]
>>> items
[0, 1, 4, 5, 6]

Si vous avez une instance de tranche s, vous pouvez obtenir de plus amples informations à ce sujet en regardant son s.start, s.stop et s.step attributs, respectivement. Par exemple:

>>> a = slice(10, 50, 2)
>>> a.start
10
>>> a.stop
50
>>> a.step
2
>>>

1. Tranche Notation

Pour faire simple, rappelez-vous tranche a une seule forme:

s[start:end:step]

et voici comment cela fonctionne:

  • s: un objet qui peut être découpé en tranches
  • start: premier indice pour démarrer l'itération
  • end: dernier indice, Notez que l'index ne sera pas step inclus dans la tranche donné
  • 0: élément sélectionner chaque index len(s)

Une autre chose à l'importation: tous 1, start>=end, step>0 peut être omis Et s'ils sont omis, leur valeur par défaut sera utilisée: [], s[::-1] , s[0] en conséquence.

variations possibles sont donc:

# mostly used variations
s[start:end]
s[start:]
s[:end]

# step related variations
s[:end:step]
s[start::step]
s[::step]

# make a copy
s[:]

NOTE:. Si <=> (en considérant que lorsque <=>), python retourne une tranche vide <=>

2. Pitfalls

La partie ci-dessus explique les caractéristiques de base sur la façon dont fonctionne la tranche, il fonctionnera sur la plupart des occasions. Cependant, il peut y avoir des pièges que vous devriez faire attention, et cette partie les explique.

index négatifs

La première chose embrouille les apprenants de python est que l'indice peut être négatif! Ne paniquez pas:. Index négatif signifie le nombre d'arrière

Par exemple:

s[-5:]    # start at the 5th index from the end of array, 
          # thus returns the last 5 elements
s[:-5]    # start at index 0, end until the 5th index from end of array, 
          # thus returns s[0:len(s)-5]

étape négative

Rendre les choses plus confuses est que <=> peut être négatif aussi!

signifie pas négatif itérer le tableau arrière. À partir de la fin au début, avec un indice d'extrémité inclus, et l'indice de démarrage exclus du résultat

Remarque : lorsque l'étape est négatif, la valeur par défaut pour <=> à <=> (alors que <=> ne fait pas égal à <=>, car <=> contient <=>) . Par exemple:

s[::-1]            # reversed slice
s[len(s)::-1]      # same as above, reversed slice
s[0:len(s):-1]     # empty list

Hors erreur de plage?

Soyez surpris: tranche ne soulève pas IndexError lorsque l'indice est hors de portée

Si l'indice est hors de portée, python fera de son mieux ensemble l'index ou <=> selon la <=> situation. Par exemple:

s[:len(s)+5]      # same as s[:len(s)]
s[-len(s)-5::]    # same as s[0:]
s[len(s)+5::-1]   # same as s[len(s)::-1], same as s[::-1]

3. Exemples

Finissons cette réponse avec des exemples explique tout ce que nous avons discuté:

# create our array for demonstration
In [1]: s = [i for i in range(10)]

In [2]: s
Out[2]: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

In [3]: s[2:]   # from index 2 to last index
Out[3]: [2, 3, 4, 5, 6, 7, 8, 9]

In [4]: s[:8]   # from index 0 up to index 8
Out[4]: [0, 1, 2, 3, 4, 5, 6, 7]

In [5]: s[4:7]  # from index 4(included) up to index 7(excluded)
Out[5]: [4, 5, 6]

In [6]: s[:-2]  # up to second last index(negative index)
Out[6]: [0, 1, 2, 3, 4, 5, 6, 7]

In [7]: s[-2:]  # from second last index(negative index)
Out[7]: [8, 9]

In [8]: s[::-1] # from last to first in reverse order(negative step)
Out[8]: [9, 8, 7, 6, 5, 4, 3, 2, 1, 0]

In [9]: s[::-2] # all odd numbers in reversed order
Out[9]: [9, 7, 5, 3, 1]

In [11]: s[-2::-2] # all even numbers in reversed order
Out[11]: [8, 6, 4, 2, 0]

In [12]: s[3:15]   # end is out of range, python will set it to len(s)
Out[12]: [3, 4, 5, 6, 7, 8, 9]

In [14]: s[5:1]    # start > end, return empty list
Out[14]: []

In [15]: s[11]     # access index 11(greater than len(s)) will raise IndexError
---------------------------------------------------------------------------
IndexError                                Traceback (most recent call last)
<ipython-input-15-79ffc22473a3> in <module>()
----> 1 s[11]

IndexError: list index out of range

Les réponses ci-dessus ne discutent pas de découpage en tranches de tableau multi-dimensionnel qui est possible en utilisant le fameux paquet NumPy:

Trancheuse peut également être appliquée à des réseaux multi-dimensionnelles.

# Here, a is a NumPy array

>>> a
array([[ 1,  2,  3,  4],
       [ 5,  6,  7,  8],
       [ 9, 10, 11, 12]])
>>> a[:2, 0:3:2]
array([[1, 3],
       [5, 7]])

Le « :2 » avant la virgule fonctionne sur la première dimension et le « 0:3:2 » après la virgule fonctionne sur la deuxième dimension.

#!/usr/bin/env python

def slicegraphical(s, lista):

    if len(s) > 9:
        print """Enter a string of maximum 9 characters,
    so the printig would looki nice"""
        return 0;
    # print " ",
    print '  '+'+---' * len(s) +'+'
    print ' ',
    for letter in s:
        print '| {}'.format(letter),
    print '|'
    print " ",; print '+---' * len(s) +'+'

    print " ",
    for letter in range(len(s) +1):
        print '{}  '.format(letter),
    print ""
    for letter in range(-1*(len(s)), 0):
        print ' {}'.format(letter),
    print ''
    print ''


    for triada in lista:
        if len(triada) == 3:
            if triada[0]==None and triada[1] == None and triada[2] == None:
                # 000
                print s+'[   :   :   ]' +' = ', s[triada[0]:triada[1]:triada[2]]
            elif triada[0] == None and triada[1] == None and triada[2] != None:
                # 001
                print s+'[   :   :{0:2d} ]'.format(triada[2], '','') +' = ', s[triada[0]:triada[1]:triada[2]]
            elif triada[0] == None and triada[1] != None and triada[2] == None:
                # 010
                print s+'[   :{0:2d} :   ]'.format(triada[1]) +' = ', s[triada[0]:triada[1]:triada[2]]
            elif triada[0] == None and triada[1] != None and triada[2] != None:
                # 011
                print s+'[   :{0:2d} :{1:2d} ]'.format(triada[1], triada[2]) +' = ', s[triada[0]:triada[1]:triada[2]]
            elif triada[0] != None and triada[1] == None and triada[2] == None:
                # 100
                print s+'[{0:2d} :   :   ]'.format(triada[0]) +' = ', s[triada[0]:triada[1]:triada[2]]
            elif triada[0] != None and triada[1] == None and triada[2] != None:
                # 101
                print s+'[{0:2d} :   :{1:2d} ]'.format(triada[0], triada[2]) +' = ', s[triada[0]:triada[1]:triada[2]]
            elif triada[0] != None and triada[1] != None and triada[2] == None:
                # 110
                print s+'[{0:2d} :{1:2d} :   ]'.format(triada[0], triada[1]) +' = ', s[triada[0]:triada[1]:triada[2]]
            elif triada[0] != None and triada[1] != None and triada[2] != None:
                # 111
                print s+'[{0:2d} :{1:2d} :{2:2d} ]'.format(triada[0], triada[1], triada[2]) +' = ', s[triada[0]:triada[1]:triada[2]]

        elif len(triada) == 2:
            if triada[0] == None and triada[1] == None:
                # 00
                print s+'[   :   ]    ' + ' = ', s[triada[0]:triada[1]]
            elif triada[0] == None and triada[1] != None:
                # 01
                print s+'[   :{0:2d} ]    '.format(triada[1]) + ' = ', s[triada[0]:triada[1]]
            elif triada[0] != None and triada[1] == None:
                # 10
                print s+'[{0:2d} :   ]    '.format(triada[0]) + ' = ', s[triada[0]:triada[1]]
            elif triada[0] != None and triada[1] != None:
                # 11
                print s+'[{0:2d} :{1:2d} ]    '.format(triada[0],triada[1]) + ' = ', s[triada[0]:triada[1]]

        elif len(triada) == 1:
            print s+'[{0:2d} ]        '.format(triada[0]) + ' = ', s[triada[0]]


if __name__ == '__main__':
    # Change "s" to what ever string you like, make it 9 characters for
    # better representation.
    s = 'COMPUTERS'

    # add to this list different lists to experement with indexes
    # to represent ex. s[::], use s[None, None,None], otherwise you get an error
    # for s[2:] use s[2:None]

    lista = [[4,7],[2,5,2],[-5,1,-1],[4],[-4,-6,-1], [2,-3,1],[2,-3,-1], [None,None,-1],[-5,None],[-5,0,-1],[-5,None,-1],[-1,1,-2]]

    slicegraphical(s, lista)

Vous pouvez exécuter ce script et d'expérimenter avec elle, voici quelques exemples que j'ai reçu du script.

  +---+---+---+---+---+---+---+---+---+
  | C | O | M | P | U | T | E | R | S |
  +---+---+---+---+---+---+---+---+---+
  0   1   2   3   4   5   6   7   8   9   
 -9  -8  -7  -6  -5  -4  -3  -2  -1 

COMPUTERS[ 4 : 7 ]     =  UTE
COMPUTERS[ 2 : 5 : 2 ] =  MU
COMPUTERS[-5 : 1 :-1 ] =  UPM
COMPUTERS[ 4 ]         =  U
COMPUTERS[-4 :-6 :-1 ] =  TU
COMPUTERS[ 2 :-3 : 1 ] =  MPUT
COMPUTERS[ 2 :-3 :-1 ] =  
COMPUTERS[   :   :-1 ] =  SRETUPMOC
COMPUTERS[-5 :   ]     =  UTERS
COMPUTERS[-5 : 0 :-1 ] =  UPMO
COMPUTERS[-5 :   :-1 ] =  UPMOC
COMPUTERS[-1 : 1 :-2 ] =  SEUM
[Finished in 0.9s]

Lors de l'utilisation d'une étape négative, notez que la réponse est décalée vers la droite de 1.

Mon cerveau semble heureux d'accepter que contient le lst[start:end] start - ième élément. Je pourrais même dire qu'il est une « hypothèse naturelle ».

Mais de temps en temps un doute se glisse dans mon cerveau et demande rassurer qu'il ne contient pas le end -. Ème élément

Dans ces moments-là, je compte sur ce théorème simple:

for any n,    lst = lst[:n] + lst[n:]

Cette jolie propriété me dit que ne contient pas lst[end:] le n -. E point parce qu'il est dans True

Notez que ce théorème est vrai pour tout <=> du tout. Par exemple, vous pouvez vérifier que

lst = range(10)
lst[:-42] + lst[-42:] == lst

retourne <=>.

En Python, la forme la plus basique pour trancher est la suivante:

l[start:end]

où est une collection l, est un indice start inclusif et est un indice end exclusif.

In [1]: l = list(range(10))

In [2]: l[:5] # first five elements
Out[2]: [0, 1, 2, 3, 4]

In [3]: l[-5:] # last five elements
Out[3]: [5, 6, 7, 8, 9]

Lors de découpage du début, vous pouvez omettre l'indice zéro, et la découpe en tranches à la fin, vous pouvez omettre l'indice final puisqu'il est redondant, alors ne soyez pas bavard:

In [5]: l[:3] == l[0:3]
Out[5]: True

In [6]: l[7:] == l[7:len(l)]
Out[6]: True

Les entiers négatifs sont utiles pour faire des décalages par rapport à la fin d'une collection:

In [7]: l[:-1] # include all elements but the last one
Out[7]: [0, 1, 2, 3, 4, 5, 6, 7, 8]

In [8]: l[-3:] # take the last 3 elements
Out[8]: [7, 8, 9]

Il est possible de fournir des indices qui sont hors limites lors du tranchage, tels que:

In [9]: l[:20] # 20 is out of index bounds, l[20] will raise an IndexError exception
Out[9]: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

In [11]: l[-20:] # -20 is out of index bounds, l[-20] will raise an IndexError exception
Out[11]: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

Gardez à l'esprit que le résultat de trancher une collection est une nouvelle collection. En outre, lorsque vous utilisez la notation des tranches dans les affectations, la durée de l'affectation de tranche ne doit pas être la même chose. Les valeurs avant et après la tranche assignée seront conservés, et la collecte rétrécissent ou se développer pour contenir les nouvelles valeurs:

In [16]: l[2:6] = list('abc') # assigning less elements than the ones contained in the sliced collection l[2:6]

In [17]: l
Out[17]: [0, 1, 'a', 'b', 'c', 6, 7, 8, 9]

In [18]: l[2:5] = list('hello') # assigning more elements than the ones contained in the sliced collection l [2:5]

In [19]: l
Out[19]: [0, 1, 'h', 'e', 'l', 'l', 'o', 6, 7, 8, 9]

Si vous ne spécifiez pas l'index de début et de fin, vous ferez une copie de la collection:

In [14]: l_copy = l[:]

In [15]: l == l_copy and l is not l_copy
Out[15]: True

Si les indices de début et de fin sont omis lors de l'exécution d'une opération d'affectation, la totalité du contenu de la collection sera remplacée par une copie de ce qui est référencé:

In [20]: l[:] = list('hello...')

In [21]: l
Out[21]: ['h', 'e', 'l', 'l', 'o', '.', '.', '.']

En plus de découpage en tranches de base, il est également possible d'appliquer la notation suivante:

l[start:end:step]

où est une collection step, est un indice <=> compris, est un indice <=> exclusif, et est un pas <=> qui peut être utilisé pour prendre toutes les nième article en <=>.

In [22]: l = list(range(10))

In [23]: l[::2] # take the elements which indexes are even
Out[23]: [0, 2, 4, 6, 8]

In [24]: l[1::2] # take the elements which indexes are odd
Out[24]: [1, 3, 5, 7, 9]

En utilisant une astuce fournit <=> utile pour inverser une collection en Python:

In [25]: l[::-1]
Out[25]: [9, 8, 7, 6, 5, 4, 3, 2, 1, 0]

Il est également possible d'utiliser des entiers négatifs pour que l'exemple <=> suivant:

In[28]:  l[::-2]
Out[28]: [9, 7, 5, 3, 1]

Cependant, en utilisant une valeur négative pour pourrait devenir très <=> source de confusion. De plus, afin d'être Pythonic, vous devriez éviter d'utiliser <=>, <=>, et en une seule <=> tranche. Dans le cas où cela est nécessaire, envisager de le faire en deux missions (une à trancher, et l'autre pas).

In [29]: l = l[::2] # this step is for striding

In [30]: l
Out[30]: [0, 2, 4, 6, 8]

In [31]: l = l[1:-1] # this step is for slicing

In [32]: l
Out[32]: [2, 4, 6]

La plupart des réponses ci-dessus sur la notation tranche efface. syntaxe d'indexation étendue utilisée pour le découpage est aList[start:stop:step] exemples de base sont

 entrer dans la description d'image ici :

Des exemples plus Slicing: 15 tranches étendues

Ce qui suit est l'exemple d'indice d'une chaîne

 +---+---+---+---+---+
 | H | e | l | p | A |
 +---+---+---+---+---+
 0   1   2   3   4   5
-5  -4  -3  -2  -1

str="Name string"

exemple tranchage: [Début: Fin: étape]

str[start:end] # items start through end-1
str[start:]    # items start through the rest of the array
str[:end]      # items from the beginning through end-1
str[:]         # a copy of the whole array

Ci-dessous l'exemple d'utilisation

print str[0]=N
print str[0:2]=Na
print str[0:7]=Name st
print str[0:7:2]=Nm t
print str[0:-1:2]=Nm ti

Je veux ajouter un exemple Bonjour tout le monde qui explique les bases de tranches pour les très débutants. Il m'a beaucoup aidé.

Ayons une liste avec six valeurs ['P', 'Y', 'T', 'H', 'O', 'N']:

+---+---+---+---+---+---+
| P | Y | T | H | O | N |
+---+---+---+---+---+---+
  0   1   2   3   4   5 

Maintenant, les plus simples tranches de cette liste sont ses sous-listes. La notation est la clé et [<index>:<index>] est de le lire comme ceci:

[ start cutting before this index : end cutting before this index ]

Maintenant, si vous faites une tranche de la liste [2:5] ci-dessus, cela se produira:

        |           |
+---+---|---+---+---|---+
| P | Y | T | H | O | N |
+---+---|---+---+---|---+
  0   1 | 2   3   4 | 5 

Vous avez fait une coupe avant l'élément avec l'index et une autre coupe 2 avant l'élément avec un indice 5. Ainsi, le résultat sera une tranche entre ces deux coupes, une liste ['T', 'H', 'O'].

À mon avis, vous comprendrez mieux et mémoriser la notation de découpage en tranches de chaîne Python si vous regardez la façon suivante (lire).

Travaillons avec la chaîne suivante ...

azString = "abcdefghijklmnopqrstuvwxyz"

Pour ceux qui ne connaissent pas, vous pouvez créer une sous-chaîne de la notation en utilisant azString azString[x:y]

En venant d'autres langages de programmation, qui est quand le sens commun est compromis. Quels sont x et y?

Je devais asseoir et exécuter plusieurs scénarios dans ma quête d'une technique de mémorisation qui me rappeler à quoi x et y sont et aider à me tartine correctement les chaînes à la première tentative.

Ma conclusion est que x et y doit être considérée comme les indices limites qui entourent les chaînes que nous voulons plus. Donc, nous devrions voir l'expression ou encore plus azString[index1, index2] plus clair que azString[index_of_first_character, index_after_the_last_character].

Voici un exemple de visualisation de cette ...

Letters   a b c d e f g h i j ...
         ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ 
Indexes  0 1 2 3 4 5 6 7 8 9 ... 
             |           |
cdefgh    index1       index2

Donc tout ce que vous devez faire si pour régler index1 et index2 aux valeurs qui entoureront la sous-chaîne désirée. Par exemple, pour obtenir la sous-chaîne « CDEFGH », vous pouvez utiliser l'index parce que azString[2:8] sur le côté gauche de « c » est 2 et celui sur la bonne taille de « h » est 8.

Rappelez-vous que nous fixons les limites. Et ces limites sont les positions où vous pouvez placer des supports qui seront enroulés autour de la sous-chaîne comme ça ...

a b [ c d e f g h ] i j

Cette astuce fonctionne tout le temps et est facile à mémoriser.

Si vous vous sentez des indices négatifs dans tranchage est source de confusion, voici très moyen facile de penser: il suffit de remplacer l'indice négatif avec len - index. Ainsi, par exemple, remplacer -3 avec len(list) - 3.

La meilleure façon d'illustrer ce découpage n'est tout simplement le montrer en interne dans le code qui implémente cette opération:

def slice(list, start = None, end = None, step = 1):
  # take care of missing start/end parameters
  start = 0 if start is None else start
  end = len(list) if end is None else end

  # take care of negative start/end parameters
  start = len(list) + start if start < 0 else start
  end = len(list) + end if end < 0 else end

  # now just execute for-loop with start, end and step
  return [list[i] for i in range(start, end, step)]

La technique de découpage de base est de définir le point de départ, le point d'arrêt, et la taille de l'étape - également connue sous le nom enjambée

.

Tout d'abord, nous allons créer une liste de valeurs à utiliser dans notre découpage en tranches.

Créer deux listes de découper, la première est une liste numérique de 1 à 9 (liste A). La seconde est une liste numérique, de 0 à 9 (Liste B)

A = list(range(1,10,1)) # start,stop,step
B = list(range(9))

print("This is List A:",A)
print("This is List B:",B)

N le nombre de 3 A et le numéro 6 de B.

print(A[2])
print(B[6])

Basic Slicing

syntaxe d'indexation allongée utilisée pour le tranchage est aList [démarrer: arrêt: étape]. L'argument de départ et l'argument étape à la fois par défaut à aucun - le seul argument requis est arrêté. Avez-vous remarqué ce qui est similaire à la façon dont gamme a été utilisée pour définir des listes A et B? En effet, l'objet de tranche représente l'ensemble des indices spécifiés par gamme (démarrage, arrêt, marche). documentation Python 3.4

Comme vous pouvez le voir, la définition ne s'arrêtera un élément rendement. Étant donné que les paramètres par défaut de démarrage zéro, cela se traduit par la récupération d'un seul élément.

Il est important de noter, le premier élément est l'index 0, pas l'indice 1. C'est pourquoi nous utilisons 2 listes pour cet exercice. les éléments de la Liste A sont numérotés en fonction de la position ordinale (le premier élément est 1, le deuxième élément est égal à 2, etc), tandis que les éléments de la liste B sont les chiffres qui seraient utilisés pour indexer ([0] pour le premier élément 0, etc. ).

Avec la syntaxe d'indexation étendue, nous récupérons une plage de valeurs. Par exemple, toutes les valeurs sont récupérées par deux points.

A[:]

Pour récupérer un sous-ensemble d'éléments, le début et les positions d'arrêt doivent être définies.

Compte tenu de la configuration aList [démarrer: arrêt], récupérer les deux premiers éléments de la liste A

Il est facile de comprendre si l'on pouvait se rapporter à trancher range, ce qui donne les index. Nous pouvons classer les trancher dans les deux catégories suivantes:


1. Aucune étape ou étape> 0. Par exemple, ou [i:j] [i:j:k] (k> 0)

Supposons que la séquence est s=[1,2,3,4,5].

  • si et 0<i<len(s) 0<j<len(s), puis [i:j:k] -> range(i,j,k)

Par exemple, [0:3:2] -> range(0,3,2) -> 0, 2

  • si ou i>len(s) j>len(s), puis ou i=len(s) j=len(s)

Par exemple, [0:100:2] -> range(0,len(s),2) -> range(0,5,2) -> 0, 2, 4

  • si ou i<0 j<0, puis ou i=max(0,len(s)+i) j=max(0,len(s)+j)

Par exemple, [0:-3:2] -> range(0,len(s)-3,2) -> range(0,2,2) -> 0

Pour un autre exemple, [0:-1:2] -> range(0,len(s)-1,2) -> range(0,4,2) -> 0, 2

  • si n'est pas spécifié i, puis i=0

Par exemple, [:4:2] -> range(0,4,2) -> range(0,4,2) -> 0, 2

  • si n'est pas spécifié j, puis [0::2] -> range(0,len(s),2) -> range(0,5,2) -> 0, 2, 4

Par exemple, [5:0:-2] -> range(5,0,-2) -> 5, 3, 1


2. Etape <0. Par exemple, i=len(s)-1 (k <0)

Supposons que la séquence est j=len(s)-1.

  • si et [100:0:-2] -> range(len(s)-1,0,-2) -> range(4,0,-2) -> 4, 2 i=max(-1,len(s)+i), puis j=max(-1,len(s)+j)

Par exemple, [-2:-10:-2] -> range(len(s)-2,-1,-2) -> range(3,-1,-2) -> 3, 1

  • si ou [:0:-2] -> range(len(s)-1,0,-2) -> range(4,0,-2) -> 4, 2 j=-1, puis ou [2::-2] -> range(2,-1,-2) -> 2, 0 [::-1] -> range(len(s)-1,-1,-1) -> range(4,-1,-1) -> 4, 3, 2, 1, 0

Par exemple, <=>

  • si ou <=> <=>, puis ou <=> <=>

Par exemple, <=>

  • si n'est pas spécifié <=>, puis <=>

Par exemple, <=>

  • si n'est pas spécifié <=>, puis <=>

Par exemple, <=>

Pour un autre exemple, <=>


En résumé

Je ne pense pas que le Python tutoriel diagramme ( cité dans diverses autres réponses) est bon que cette suggestion fonctionne pour la foulée positive, mais ne le fait pas pour un pas négatif.

Voici le schéma:

 +---+---+---+---+---+---+
 | P | y | t | h | o | n |
 +---+---+---+---+---+---+
 0   1   2   3   4   5   6
-6  -5  -4  -3  -2  -1

D'après le diagramme, je pense être a[-4,-6,-1] yP mais il est ty.

>>> a = "Python"
>>> a[2:4:1] # as expected
'th'
>>> a[-4:-6:-1] # off by 1
'ty'

Qu'est-ce toujours travailler est de penser en caractères ou machines à sous et utiliser l'indexation comme un intervalle semi-ouvert -. Droit ouvert si la foulée positive gauche ouverte si foulée négative

De cette façon, je peux penser à comme a[-4:-6:-1] dans la terminologie intervalle a(-6,-4].

 +---+---+---+---+---+---+
 | P | y | t | h | o | n |
 +---+---+---+---+---+---+
   0   1   2   3   4   5  
  -6  -5  -4  -3  -2  -1

 +---+---+---+---+---+---+---+---+---+---+---+---+
 | P | y | t | h | o | n | P | y | t | h | o | n |
 +---+---+---+---+---+---+---+---+---+---+---+---+
  -6  -5  -4  -3  -2  -1   0   1   2   3   4   5  
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top