Comment vider une liste?

356

Il semble tellement "sale" de vider une liste de cette façon:

while len(alist) > 0 : alist.pop()

Existe-t-il un moyen clair de le faire?

DrFalk3n
la source
28
Alors pourquoi les dict et les ensembles python ont-ils une méthode clear (), mais pas des listes?
job
13
Mais s'il existe plusieurs références à l'objet, cela peut être utile.
Ned Deily
3
Cela peut être utile si j'ai besoin d'effacer une liste partagée sur les processus au moment de l'exécution et que je n'ai pas besoin d'attendre le piratage (ou je me trompe? Ai-je mal compris le garbage collection?). Aussi, si je veux vérifier chaque élément sauté, je peux le déboguer alors que je ne peux pas utiliser le découpage (ou je me trompe). Je n'ai pas besoin d'arrêter l'exécution du processus lors de l'effacement de ma liste.
DrFalk3n
2
@ S.Lott Ce n'est pas parce que vous ne comprenez pas pourquoi c'est important que le reste d'entre nous ne le fait pas. Si plusieurs objets dépendent d'une liste commune, cela importera. Dans plusieurs modèles de conception, cela est important. Le ramasse-miettes signifie que vous n'avez pas à nettoyer après vous-même; ce n'est pas une licence pour faire plus de gâchis.
UpAndAdam
4
Nonobstant toute autre, de meilleures réponses, votre code initial aurait pu être écrit: while alist: alist.pop ()
MrWonderful

Réponses:

570

Cela supprime en fait le contenu de la liste, mais ne remplace pas l'ancienne étiquette par une nouvelle liste vide:

del lst[:]

Voici un exemple:

lst1 = [1, 2, 3]
lst2 = lst1
del lst1[:]
print(lst2)

Par souci d'exhaustivité, l'affectation de tranche a le même effet:

lst[:] = []

Il peut également être utilisé pour réduire une partie de la liste tout en remplaçant une partie en même temps (mais cela sort du cadre de la question).

Notez que faire lst = []ne vide pas la liste, crée simplement un nouvel objet et le lie à la variable lst, mais l'ancienne liste aura toujours les mêmes éléments, et l'effet sera apparent si elle avait d'autres liaisons de variable.

fortran
la source
3
Deux autres questions: qu'est-ce que "del" exactement? (J'en déduis que ça supprime les choses mais je ne sais pas vraiment de quoi il s'agit) et 2e: Comment lisez-vous (à haute voix) [:]
OscarRyz
2
Pour une bonne explication de del, je me réfère aux documents: docs.python.org/reference/simple_stmts.html#the-del-statement
fortran
14
Habituellement, je ne lis pas à haute voix le code python xD, mais si je le devais, je pense que je dirais "tranche du début à la fin de la liste l".
fortran
2
@jellybean complètement involontaire ^ _ ^ L'anglais n'est pas ma langue maternelle, donc je n'ai vraiment pas remarqué le contraste entre les deux commentaires.
fortran
si nous le faisons l = [] l'ancien contenu de la liste ne sera-t-il pas récupéré par Python GC?
Alex Punnen
169

Si vous utilisez Python 3.3 ou mieux, vous pouvez utiliser la clear()méthode list, qui est parallèle à clear()des dict, set, dequeet d' autres types de conteneurs mutable:

alist.clear()  # removes all items from alist (equivalent to del alist[:])

Selon la page de documentation liée, la même chose peut également être obtenue avec alist *= 0.

Pour résumer, il existe quatre façons équivalentes d'effacer une liste sur place (tout à fait contrairement au Zen de Python !):

  1. alist.clear() # Python 3.3+
  2. del alist[:]
  3. alist[:] = []
  4. alist *= 0
Eugene Yarmash
la source
6
Cette réponse devrait être au top, qu'est-ce qui ne va pas avec stackoverflow!
BreakBadSP
clear () est mieux.
sailfish009
61

Tu pourrais essayer:

alist[:] = []

Ce qui signifie: Splice dans la liste [](0 éléments) à l'emplacement [:](tous les index du début à la fin)

Le [:] est l'opérateur de tranche. Voir cette question pour plus d'informations.

Adam Batkin
la source
4
Pourquoi pas juste alist = []?
mitenka
16
@mitenka qui ne vide pas la liste, il écrase la variable alistavec une liste différente qui se trouve être vide. Si quelqu'un d'autre avait une référence à la liste d'origine, cela reste tel quel (c'est-à-dire qu'il contient tout ce qui s'y trouvait pour commencer)
Adam Batkin
@mitenka Une autre raison est que alist.clear()ou alist[:] = []aide à vérifier qu'il alists'agit vraiment d'une liste. Supposons que vous soyez alistrevenu d'une fonction foo(). Vous pensiez avoir foorenvoyé une liste, mais en effet, elle a renvoyé un None. L'utilisation alist = []ne peut pas attraper cette erreur.
aafulei
32

il s'avère qu'avec python 2.5.2, del l[:]est légèrement plus lent que l[:] = []par 1.1 usec.

$ python -mtimeit "l=list(range(1000))" "b=l[:];del b[:]"
10000 loops, best of 3: 29.8 usec per loop
$ python -mtimeit "l=list(range(1000))" "b=l[:];b[:] = []"
10000 loops, best of 3: 28.7 usec per loop
$ python -V
Python 2.5.2
Dan D.
la source
1
En Python 2.7.2, sur ma machine, ils sont à peu près les mêmes. Ils fonctionnent tous les deux de 13,5 à 13,7 usec par boucle.
leetNightshade
Vous devez également mesurer python3 -mtimeit "l = list (range (1000))" "b = l [:]" pour calculer "b [:] = []" et "del b [:]". Faites-le et lol ...
rockdaboot
1
J'ai fait le benchmark avec python 3.5 et je suis d'accord avec leetNightshade. .clear(), del b[:]et b[:]=[]tout tourne de la même manière ( b[:]=[]étant légèrement plus lent.
Conchylicultor
5
lst *= 0

a le même effet que

lst[:] = []

C'est un peu plus simple et peut-être plus facile à retenir. A part ça, il n'y a pas grand chose à dire

L'efficacité semble être à peu près la même

Ivan Hoffmann
la source
1
Par souci d'exhaustivité, il convient de mentionner que tout entier donné inférieur ou égal à 0aurait le même effet. C'est un truc assez sympa cependant, je suis un peu triste, qu'il n'ait pas reçu beaucoup d'attention ..
Peter Varo
-1
list = []

sera réinitialisé listdans une liste vide.

Notez que vous ne devez généralement pas masquer les noms de fonctions réservés, tels que list, qui est le constructeur d'un objet liste - vous pouvez utiliser lstou à la list_place, par exemple.

Mark Rushakoff
la source
38
Non: cela ne modifiera pas la liste, cela affecte simplement une liste vide à la variable list. Si vous vous attendiez à ce qu'une fonction modifie une liste passée (par exemple), cela ne ferait pas ce que vous voulez.
Adam Batkin,
10
Pas vraiment. La question est "Comment vider une liste" et non "Comment assigner une variable contenant une liste"
Adam Batkin
6
la question n'était pas ambiguë, l'extrait d'opération faisait sortir des éléments de la liste (c'est tout, la modifiait en place) ...
fortran
7
En outre, "liste" ne doit pas être utilisé comme nom de variable, car il s'agit du type "liste". De nombreux développeurs Python utilisent "L" comme nom de variable de liste, mais je préfère "lst".
steveha
1
Parfois, vous voulez juste que la liste soit vidée et c'est aussi bon que n'importe laquelle des méthodes proposées. Probablement encore plus vite
smac89
-3

Un autre code simple que vous pourriez utiliser (selon votre situation) est:

index=len(list)-1

while index>=0:
    del list[index]
    index-=1

Vous devez commencer l'index à la longueur de la liste et revenir en arrière par rapport à l'index à 0, en avant car cela vous aboutirait à un index égal à la longueur de la liste, celui-ci n'étant que réduit de moitié.

Assurez-vous également que la ligne while a un signe «supérieur ou égal à». L'omission vous laissera la liste [0] restante.

Donald
la source
15
réinventer la roue avec un cube
CONvid19
Haha. C'est la deuxième réponse bizarre (+ un commentaire approprié) que j'ai rencontrée sur SO. Il devrait y avoir un site pour ces choses mémorables: D
akinuri