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]
?
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
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.
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]
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".
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]
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
).
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:
"Mais comment ???" ... Continuez votre lecture! (Nous pouvons le faire en 2 étapes)
Spécifiez "index de début" et "index de fin" dans les deux sens, ligne et colonne.
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!)
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:
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! :)
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é!
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'
Le troisième paramètre est le pas. Donc [:: 3] renverrait chaque 3ème élément de la liste/chaîne.
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.