web-dev-qa-db-fra.com

Qu'est-ce que :: (double-points) dans Python lors de la souscription de séquences?

Je sais que je peux utiliser quelque chose comme string[3:4] pour obtenir une sous-chaîne en Python, mais que signifie 3 dans somesequence[::3]?

219
Aillyn

cela signifie "rien pour le premier argument, rien pour le second, et saute de trois". Tous les trois éléments de la séquence sont tranchés. Tranches étendues c'est ce que vous voulez. Nouveau dans Python 2.3

205

Les adresses de tranche de séquence Python peuvent être écrites sous la forme [start: end: step] et n'importe quel début, arrêt ou fin peuvent être supprimés. a[::3] est chaque troisième élément de la séquence.

126
deinst

seq[::n] est une séquence de chaque n- ème élément de la séquence entière.

Exemple:

>>> range(10)[::2]
[0, 2, 4, 6, 8]

La syntaxe est la suivante:

seq[start:end:step]

Alors tu peux faire:

>>> range(100)[5:18:2]
[5, 7, 9, 11, 13, 15, 17]
68
Yuval Adam

Explication

s[i:j:k] est, selon la documentation , "tranche de s de i à j avec l'étape k". Lorsque i et j sont absents, la séquence entière est supposée et ainsi s[::k] signifie "chaque k-ième élément".

Exemples

Commençons par initialiser une liste:

>>> s = range(20)
>>> s
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]

Prenons tous les 3rd élément de s:

>>> s[::3]
[0, 3, 6, 9, 12, 15, 18]

Prenons tous les 3rd élément de s[2:]:

>>> s[2:]
[2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]
>>> s[2::3]
[2, 5, 8, 11, 14, 17]

Prenons tous les 3rd élément de s[5:12]:

>>> s[5:12]
[5, 6, 7, 8, 9, 10, 11]
>>> s[5:12:3]
[5, 8, 11]

Prenons tous les 3rd élément de s[:10]:

>>> s[:10]
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> s[:10:3]
[0, 3, 6, 9]
45
Bolo

TL; DR

Cet exemple visuel vous montrera comment sélectionner proprement des éléments dans une matrice NumPy (tableau à 2 dimensions) de manière très amusante (je vous promets). L'étape 2 ci-dessous illustre l'utilisation de ce "double point" :: en question.

(Attention: ceci est un exemple spécifique au tableau NumPy dans le but d’illustrer le cas d’utilisation de "doubles points" :: pour sauter des éléments dans plusieurs axes. Cet exemple ne couvre pas le caractère natif Python structures de données comme List).

Un exemple concret pour les gouverner tous ...

Disons que nous avons une matrice NumPy qui ressemble à ceci:

In [1]: import numpy as np

In [2]: X = np.arange(100).reshape(10,10)

In [3]: X
Out[3]:
array([[ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9],
       [10, 11, 12, 13, 14, 15, 16, 17, 18, 19],
       [20, 21, 22, 23, 24, 25, 26, 27, 28, 29],
       [30, 31, 32, 33, 34, 35, 36, 37, 38, 39],
       [40, 41, 42, 43, 44, 45, 46, 47, 48, 49],
       [50, 51, 52, 53, 54, 55, 56, 57, 58, 59],
       [60, 61, 62, 63, 64, 65, 66, 67, 68, 69],
       [70, 71, 72, 73, 74, 75, 76, 77, 78, 79],
       [80, 81, 82, 83, 84, 85, 86, 87, 88, 89],
       [90, 91, 92, 93, 94, 95, 96, 97, 98, 99]])

Dites pour une raison quelconque, votre patron veut que vous sélectionniez les éléments suivants:

enter image description here

"Mais comment ???" ... Continuez votre lecture! (Nous pouvons le faire en 2 étapes)

Étape 1 - Obtenir un sous-ensemble

Spécifiez "index de début" et "index de fin" dans les deux sens, ligne et colonne.

enter image description here

Dans du code:

In [5]: X2 = X[2:9,3:8]

In [6]: X2
Out[6]:
array([[23, 24, 25, 26, 27],
       [33, 34, 35, 36, 37],
       [43, 44, 45, 46, 47],
       [53, 54, 55, 56, 57],
       [63, 64, 65, 66, 67],
       [73, 74, 75, 76, 77],
       [83, 84, 85, 86, 87]])

Remarquez maintenant que nous venons d'obtenir notre sous-ensemble, avec l'utilisation de la technique simple d'indexation de début et de fin. Ensuite, comment faire ce "saut" ... (lisez la suite!)

Étape 2 - Sélectionnez les éléments (avec l'argument "étape de saut")

Nous pouvons maintenant spécifier les "étapes de saut" dans les directions rangée et colonne (pour sélectionner des éléments de manière "sautée") comme ceci:

enter image description here

En code (notez les doubles points):

In [7]: X3 = X2[::3, ::2]

In [8]: X3
Out[8]:
array([[23, 25, 27],
       [53, 55, 57],
       [83, 85, 87]])

Nous venons de sélectionner tous les éléments nécessaires! :)

Consolider les étapes 1 (début et fin) et 2 (sauter)

Maintenant que nous connaissons le concept, nous pouvons facilement combiner les étapes 1 et 2 en une étape consolidée - pour des raisons de compacité:

In [9]: X4 = X[2:9,3:8][::3,::2]

    In [10]: X4
    Out[10]:
    array([[23, 25, 27],
           [53, 55, 57],
           [83, 85, 87]])

Terminé!

18
Atlas7

Lors du découpage en Python, le troisième paramètre est l'étape. Comme d'autres l'ont mentionné, voir Extended Slices pour une vue d'ensemble de Nice.

Avec cette connaissance, [::3] signifie simplement que vous n'avez spécifié aucun index de début ou de fin pour votre tranche. Etant donné que vous avez spécifié une étape, 3, cela prendra toutes les trois entrées de something à partir du premier index. Par exemple:

>>> '123123123'[::3]
'111'
13
Justin Ethier

Le troisième paramètre est le pas. Donc [:: 3] renverrait chaque 3ème élément de la liste/chaîne.

6
mshafrir

Vous pouvez également utiliser cette notation dans vos propres classes personnalisées pour lui permettre de faire ce que vous voulez

class C(object):
    def __getitem__(self, k):
        return k

# Single argument is passed directly.
assert C()[0] == 0

# Multiple indices generate a Tuple.
assert C()[0, 1] == (0, 1)

# Slice notation generates a slice object.
assert C()[1:2:3] == slice(1, 2, 3)

# If you omit any part of the slice notation, it becomes None.
assert C()[:] == slice(None, None, None)
assert C()[::] == slice(None, None, None)
assert C()[1::] == slice(1, None, None)
assert C()[:2:] == slice(None, 2, None)
assert C()[::3] == slice(None, None, 3)

# Tuple with a slice object:
assert C()[:, 1] == (slice(None, None, None), 1)

# Ellipsis class object.
assert C()[...] == Ellipsis

On peut alors ouvrir des objets slice comme:

s = slice(1, 2, 3)
assert s.start == 1
assert s.stop == 2
assert s.step == 3

Ceci est notamment utilisé dans Numpy pour découper des tableaux multidimensionnels dans n'importe quelle direction.

Bien sûr, toute API doit utiliser ::3 avec la sémantique habituelle "tous les 3".

Python utilise le :: pour séparer les valeurs End, Start et Step.

5