web-dev-qa-db-fra.com

Pop plusieurs éléments au début et à la fin d'une liste

Supposons que j'ai une liste d'éléments comme ceci:

mylist=['a','b','c','d','e','f','g','h','i']

Je veux faire apparaître deux éléments de gauche (c'est-à-dire a et b) et deux éléments de droite (c'est-à-dire h, i). Je veux le plus concis et propreté façon de le faire. Je pourrais le faire moi-même:

for x in range(2):
    mylist.pop()
    mylist.pop(0)

Toute autre alternative?

18
ehsan88

Du point de vue de la performance:

  • mylist = mylist[2:-2] et del mylist[:2];del mylist[-2:] sont équivalents
  • ils sont environ 3 fois plus rapides que la première solution for _ in range(2): mylist.pop(0); mylist.pop()

Code

iterations = 1000000
print timeit.timeit('''mylist=range(9)\nfor _ in range(2): mylist.pop(0); mylist.pop()''', number=iterations)/iterations
print timeit.timeit('''mylist=range(9)\nmylist = mylist[2:-2]''', number=iterations)/iterations
print timeit.timeit('''mylist=range(9)\ndel mylist[:2];del mylist[-2:]''', number=iterations)/iterations

sortie

1.07710313797e-06

3.44465017319e-07

3.49956989288e-07

17
bold

Vous pouvez découper une nouvelle liste en conservant l'ancienne liste telle quelle:

mylist=['a','b','c','d','e','f','g','h','i']
newlist = mylist[2:-2]

newlist retourne maintenant:

['c', 'd', 'e', 'f', 'g']

Vous pouvez également écraser la référence à l'ancienne liste:

mylist = mylist[2:-2]

Les deux approches ci-dessus utiliseront plus de mémoire que celle ci-dessous.

Ce que vous essayez de faire vous-même est convivial pour la mémoire, avec l'inconvénient de changer l'ancienne liste, mais popleft n'est pas disponible pour les listes en Python, c'est une méthode de l'objet collections.deque.

Cela fonctionne bien dans Python 3:

for x in range(2):
    mylist.pop(0)
    mylist.pop()

En Python 2, utilisez uniquement xrange et pop:

for _ in xrange(2):
    mylist.pop(0)
    mylist.pop()

Le moyen le plus rapide de supprimer, comme le suggère Martijn, (cela supprime uniquement la référence de la liste aux éléments, pas nécessairement les éléments eux-mêmes):

del mylist[:2]
del mylist[-2:]
10
Aaron Hall

Si vous ne souhaitez pas conserver les valeurs, vous pouvez supprimer les index:

del myList[-2:], myList[:2]

Cela nécessite tout de même que tous les éléments restants soient déplacés vers le haut dans la liste. Cela nécessite également deux appels .popleft(), mais au moins maintenant, l’objet de liste peut gérer les déplacements en une étape.

Aucun nouvel objet de liste n'est créé.

Démo:

>>> myList = ['a','b','c','d','e','f','g','h','i']
>>> del myList[-2:], myList[:2]
>>> myList
['c', 'd', 'e', 'f', 'g']

Cependant, à cause de votre utilisation de popleft, je soupçonne fortement que vous travaillez plutôt avec un objet collections.dequeue() . Si tel est le cas, * continuez à utiliser popleft(), ce qui est bien plus efficace que le découpage en tranches ou del sur un objet de la liste.

7
Martijn Pieters

2 premiers éléments: myList[:2]
2 derniers éléments: mylist[-2:]

Alors myList[2:-2]

2
zer0uno

Python3 a quelque chose de cool, semblable au reste dans JS (mais une douleur si vous avez besoin de sortir beaucoup de choses)

mylist=['a','b','c','d','e','f','g','h','i']
_, _, *mylist, _, _ = mylist
mylist == ['c', 'd', 'e', 'f', 'g']  # true
0
mastercoder8