2013-09-02 4 views
0

Je suis nouveau à Python et essayait de comprendre le découpage de liste.pourquoi la liste des tranches dans la direction de droite à gauche renvoie la liste vide?

Cette question a peut-être été répondue quelque part (j'ai essayé de chercher des questions existantes et leurs réponses, mais je n'ai pas trouvé ce que je cherchais).

J'ai une liste, sample_list = [1,2,3,4,5,6,7].

Maintenant, quand j'essaie d'accéder à:

print sample_list [-2: 2]

ou,

print sample_list [-3: -7]

Dans les deux cas , Je reçois une liste vide. Ne devrait-il pas imprimer au moins [6,7] ou [5,6,7] respectivement, en suivant la convention de gauche à droite? Je sais que je fais quelque chose de mal en termes de sémantique.

(en essayant d'imprimer la liste dans la direction de droite à gauche?)

Je voudrais comprendre la logique derrière la liste vide. Que se passe-t-il ici?

Merci.

+0

Indice: Qu'est-ce qu'il imprime si vous faites 'sample_list [-2:]'? Jetez également un oeil à [cette question] (http://stackoverflow.com/questions/509211/the-python-slice-notation) –

+0

Dans 'sample_list [x: y]', l'index x est la limite inférieure et y est le supérieur. vous faites 'sampe_list [-2: 2]', mais dans la liste l'élément à l'index 2 vient en premier. –

+0

@BurhanKhalid le lien est certainement utile. En fait, l'un des messages répond un peu à mes doutes sur les raisons pour lesquelles je reçois des listes vides plutôt qu'une erreur: "Python est gentil avec le programmeur (s'il y a moins d'éléments que ce que vous demandez. a [: - 2] et un seul contient un élément,) vous obtenez une liste vide au lieu d'une erreur. " – dkumar

Répondre

3

Rappelez-vous que les indices commencent à 0:

sample_list = [1,2,3,4,5,6,7] 
#    0 1 2 3 4 5 6 

Lorsque vous faites sample_list[-2:2], vous essayez d'obtenir le deuxième dernier élément au troisième élément.

Mais vous ne pouvez pas passer du négatif au positif (sauf si vous ajoutez une étape négative). Si vous souhaitez obtenir une liste inversée, puis ajoutez un step:

>>> print sample_list[2:-2][::-1] 
[5, 4, 3] 

C'est le même problème avec votre deuxième exemple. Vous essayez de revenir en arrière avec indicies négatif, mais vous ne pouvez pas ... à moins que ... vous ajouter dans une étape négative !:

>>> print sample_list[-3:-7:-1] 
[5, 4, 3, 2] 
3

Si vous voulez couper de droite à gauche, vous avez besoin pour fournir un résultat négatif step: sample_list[-2:2:-1]. Cela inversera également l'ordre des valeurs. Une tranche comme [-2:2] n'est pas vide de sens. Si vous faites sample_list[-2:2] sur une liste de deux longueurs, vous obtiendrez une copie de l'ensemble. Dans une liste de longueur trois, vous obtiendrez une tranche avec seulement l'élément du milieu. C'est seulement pour les listes de longueur 4 ou plus, vous obtenez une tranche vide. S'ils se renversaient automatiquement, alors certains de ces cas seraient ambigus. Edit: Laissez-moi essayer de faire une explication plus complète.

La syntaxe de tranche de Python est implémentée par slice objets. C'est-à-dire L[start:stop:step] est équivalent à L[slice(start, stop, step)]. (Eh bien, voici comment cela fonctionne dans Python 3.Pour rétrocompatibilité raisonne Python 2 a également une approche plus ancienne, en utilisant __getslice__ et __setslice__ méthodes, mais la nouvelle façon avec slice objets fonctionne aussi.)

Lorsque vous prenez une tranche ou d'une liste ou tuple, vous obtenez toujours des éléments en commençant par l'index start et continue jusqu'à l'élément juste avant stop. Le paramètre step décrit la taille des étapes prises, 2 signifiant toutes les autres valeurs, et -1 signifiant des étapes inverses.

Une autre façon d'y penser est qu'une tranche L[start:stop:step] est presque équivalente à la compréhension de la liste [L[i] for i in range(start, stop, step)]. Les différences sont seulement dans ce qui arrive quand certaines des valeurs sont négatives ou non fournies.

La règle de gestion des valeurs négatives est simple (et identique pour l'indexation sans découpage). Pour start et stop, il suffit d'ajouter la longueur de la séquence à une valeur négative. Ainsi, pour positif x et y, la tranche L[-x:-y] est exactement équivalente à L[len(L)-x:len(L)-y]. Les valeurs négatives step ne sont pas transformées. Contrairement à l'indexation régulière, le découpage en tranches ne soulève jamais d'exceptions pour les index hors de portée. Si les index ne sont pas valides, vous pouvez obtenir un résultat vide, ou juste moins de valeurs que ce que la section demandait.

Tous les arguments d'une tranche ne sont pas obligatoires. Un constructeur d'objet slice attribue None comme valeurs par défaut pour tout argument non fourni. Ce que ces None signifient pour start et stop diffère selon le signe de step, et aussi sur les dimensions de la liste qui est découpée.

Si step est None il est toujours traitée comme si elle était 1. Si step est positif (ou None), une valeur start de None est traitée comme si elle était 0 et une valeur stop de None est traitée comme len(L). Si step est négatif, une valeur start de None est traitée comme -1 et stop la valeur de None est traitée comme -len(L)-1.

Donc, pour encercler revenir à votre question, quand vous faites la tranche sample_list[-2:2], plusieurs choses se produisent:

Tout d'abord, un objet slice est créé, comme si vous l'avez fait slice(-2, 2). Cet objet tranche aura un step de None, puisque vous n'avez pas fourni une troisième valeur.

Ensuite, le slice est passé à la liste et les valeurs sont interprétées. Puisque step était None, la valeur par défaut de 1 est utilisée. Puisque start est négatif, la longueur de la liste y est ajoutée.

Enfin, les résultats sont compris. Pour votre liste d'exemple avec sept valeurs, vous obtenez l'équivalent de [sample_list[i] for i in range(5, 2, 1)]. Puisque la gamme est vide, la tranche est aussi. En fonction de ce que vous vouliez, vous pouvez résoudre ce problème de différentes façons.Vous pouvez le laisser être et vous obtiendrez des résultats uniquement pour les listes de sources très courtes, où len(L)-2 est inférieur à 2. Alternativement, vous pouvez échanger l'ordre de vos deux premiers arguments et obtenir le résultat [3,4,5]. Ou vous pouvez ajouter un step négatif et le découper de droite à gauche, ce qui donne [6, 5, 4].

Questions connexes