2009-11-09 11 views
2

Question d'origine: Quelqu'un peut-il me dire comment utiliser les "listes de tranches" et les "ellipses"? Quand sont-ils utiles? Merci."Listes de tranches" et "l'ellipse" en Python; Tranches de listes et listes de listes avec listes de tranches

Voici ce que dit la définition de la langue à propos de "slice_list" et "ellipsis"; La réponse d'Alex Martelli souligne leur origine, ce qui n'est pas ce que j'avais imaginé.

[http://docs.python.org/reference/expressions.html#tok-slicing][1]

5.3.3. Slicings

extended_slicing :: = primaire "[" liste_tranches "]"

liste_tranches :: = slice_item ("" slice_item) * [ ""]

slice_item: : = expression | proper_slice | ellipsis

:: = ellipsis "..."

[1]: http://docs.python.org/reference/expressions.html#tok-slicing

Au cas où quelqu'un (comme moi) est à la recherche de moyens d'attaquer une liste (ou une liste de listes) avec une liste de tranches, voici 5 façons d'obtenir une liste d'éléments d'une liste qui sont sélectionnés par une liste de tranches et 2 façons de faire la même chose à une liste de listes, dans ce cas en appliquant une tranche par liste. La sortie est dans un commentaire à la fin. Je trouve h5, l'exemple qui utilise des boucles imbriquées, le plus difficile à comprendre si des noms de variables significatifs ne sont pas utilisés (mis à jour).

#!/usr/bin/env python 



import itertools 

puz = [(i + 100) for i in range(40)] 
puz1 = list(puz) 
puz2 = [(i + 200) for i in range(40)] 
puz3 = [(i + 300) for i in range(40)] 
puzs = [puz1,puz2,puz3] 

sa = slice(0,1,1) 
sb = slice(30,39,4) 
sc = slice(-1, -15,-5) 
ss = [sa,sb,sc] 

def mapfunc(a,b): 
    return a[b] 

f = map(mapfunc,[puz] * len(ss),ss) 
print "f = ", f #same as g below 

g = [ puz[i] 
    for i in ss ] 
print "g = ",g #same as f, above 

h1 = [ i 
    for i in itertools.chain(puz[sa],puz[sb],puz[sc]) ] 
print "h1 = ", h1 #right 

h2 = [ i 
    for i in itertools.chain(*(map(mapfunc,[puz] * len(ss),ss))) ] 
print "h2 = ",h2 #right 

h3 = [ i 
    for i in itertools.chain(*f) ] 
print "h3 = ",h3 #right 

h4 = [ i 
    for i in itertools.chain(*g) ] 
print "h4 = ", h4 #also right 

h5 = [] 
for slice_object in ss: 
    for list_element in puz[slice_object]: 
     h5.append(list_element) 
print "h5 = ", h5 #right, too 

print "==============================" 

hh1 = [ i 
    for i in itertools.chain(*(map(mapfunc,puzs,ss))) ] 
print "hh1 = ",hh1 #right 

puz_s_pairs = zip(puzs,ss) 
#print "puz_s_pairs = ",puz_s_pairs 
hh2 = [ i 
    for i in itertools.chain(*(map(mapfunc,*zip(*puz_s_pairs)))) ] 
print "hh2 = ",hh2 #right 

''' 
>>> execfile(r'D:/cygwin/home/usr01/wrk/py/pyexpts/list_of_slices_of_list.02.py') 
f = [[100], [130, 134, 138], [139, 134, 129]] 
g = [[100], [130, 134, 138], [139, 134, 129]] 
h1 = [100, 130, 134, 138, 139, 134, 129] 
h2 = [100, 130, 134, 138, 139, 134, 129] 
h3 = [100, 130, 134, 138, 139, 134, 129] 
h4 = [100, 130, 134, 138, 139, 134, 129] 
h5 = [100, 130, 134, 138, 139, 134, 129] 
============================== 
hh1 = [100, 230, 234, 238, 339, 334, 329] 
hh2 = [100, 230, 234, 238, 339, 334, 329] 
''' 

Répondre

10

Les listes de tranches et ellipses ont été introduites à l'origine en Python pour fournir une bonne syntaxe de sucre pour le précesseur de numpy (bon vieux numérique). Si vous utilisez numpy (pas de raison de revenir à l'un de ses prédécesseurs!), Vous devriez bien sûr les utiliser; Si pour une raison étrange vous faites votre propre implémentation de tableaux multidimensionnels super-flexibles, vous voudrez certainement étudier la façon dont numpy les utilise et probablement l'imiter de près (est assez bien conçu après tout). Je ne peux pas penser à de bonnes utilisations au-delà des tableaux multidimensionnels.

+0

Ah. Je ne dois donc pas penser à des "slicelists" comme un moyen de scinder arbitrairement, plusieurs listes de listes dans une expression compacte, alors. Pitié. J'avais presque un usage pour ça. – behindthefall

+0

Pour "exécutions de listes", lire "exécute à partir d'une seule liste unidimensionnelle". – behindthefall

+1

@behindthefalls, non, les exécutions sont normalement extraites avec itertools.groupby - aucune syntaxe spéciale pour cela. Vous pourriez bien sûr implémenter une telle syntaxe dans vos propres objets, pas sûr que ce serait tout ce qui est lisible pour la plupart des gens. –

3

Numpy les utilise pour implémenter le découpage de matrice.

+2

Ellipsis - rarement utilisé. Tranchage - commun. –

1

Je ne suis pas trop sûr de l'ellipse, donc je ne vais pas aborder cela, de peur que je ne vous donne une mauvaise réponse.

va ici trancher la liste:

J'espère que vous savez que la liste indeces commencent à 0.

l = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] 

indexation dans une liste:

l[0] 
>>> 0 

l[5] 
>>> 5 

Slicing une liste.Le premier indice est inclus, mais pas le dernier:

l[0:5] 
>>> [0, 1, 2, 3, 4] 

l[2:5] 
>>> [2, 3, 4] 

Retour la liste complète comme une tranche:

l[:] 
>>> [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] 

obtenir une tranche de la liste contenant tous les éléments, y compris et après le 3ème indice:

l[3:] 
>>> [3, 4, 5, 6, 7, 8, 9] 

Obtenez une tranche de la liste contenant tous les éléments jusqu'à, mais non compris le 5ème indice:

l[:5] 
>>> [0, 1, 2, 3, 4] 

Voici quelque chose que vous ne penseriez pas python faire:

l[5:18] # note: there is no 18th index in this list 
>>> [5, 6, 7, 8, 9] 
+1

Notez que l'option l [:] est un raccourci pour copier le tableau et vous le verrez assez fréquemment. –

+0

C'est quand je me rends compte que le langage vous permet d'avoir deux ou plusieurs expressions séparées par des virgules, ce qui me laisse perplexe! ;-) – behindthefall