Est-il possible de supprimer plusieurs éléments d'une liste en même temps? Si je veux supprimer des éléments aux index 0 et 2, et essayer quelque chose comme del somelist[0]
, suivi de del somelist[2]
, la deuxième instruction supprimera réellement somelist[3]
.
Je suppose que je pourrais toujours supprimer les éléments les plus numérotés en premier, mais j'espère qu'il existe un meilleur moyen.
somelist = [ lst[i] for i in xrange(len(lst)) if i not in set(indices) ]
:?Pour une raison quelconque, je n'aime aucune des réponses ici. Oui, ils fonctionnent, mais à proprement parler, la plupart d'entre eux ne suppriment pas des éléments d'une liste, n'est-ce pas? (Mais faire une copie puis remplacer l'original par la copie éditée).
Pourquoi ne pas simplement supprimer d'abord l'index le plus élevé?
Y a-t-il une raison à cela? Je ferais juste:
Si vous ne voulez vraiment pas supprimer les éléments à l'envers, alors je suppose que vous devriez simplement déincrémenter les valeurs d'index qui sont supérieures au dernier index supprimé (vous ne pouvez pas vraiment utiliser le même index puisque vous avez une liste différente) ou utiliser une copie de la liste (qui ne serait pas «supprimer» mais remplacer l'original par une copie modifiée).
Est-ce que je manque quelque chose ici, une raison de NE PAS supprimer dans l'ordre inverse?
la source
Si vous supprimez plusieurs éléments non adjacents, ce que vous décrivez est le meilleur moyen (et oui, assurez-vous de partir de l'index le plus élevé).
Si vos éléments sont adjacents, vous pouvez utiliser la syntaxe d'affectation de tranche:
la source
del a[2:10]
avec le même effet.Vous pouvez utiliser
numpy.delete
comme suit:Si cela ne vous dérange pas de finir avec un
numpy
tableau à la fin, vous pouvez omettre le fichier.tolist()
. Vous devriez également voir des améliorations de vitesse assez importantes, ce qui en fait une solution plus évolutive. Je ne l'ai pas comparé, mais lesnumpy
opérations sont du code compilé écrit en C ou en Fortran.la source
En tant que spécialisation de la réponse de Greg, vous pouvez même utiliser une syntaxe de tranche étendue. par exemple. Si vous souhaitez supprimer les éléments 0 et 2:
Cela ne couvre aucune sélection arbitraire, bien sûr, mais cela peut certainement fonctionner pour supprimer deux éléments.
la source
En tant que fonction:
S'exécute en n log (n) temps, ce qui devrait en faire la solution correcte la plus rapide à ce jour.
la source
n log n
? Vraiment? Je ne pense pas que cedel list[index]
soit O (1).Alors, vous souhaitez essentiellement supprimer plusieurs éléments en un seul passage? Dans ce cas, la position de l'élément suivant à supprimer sera compensée par le nombre de suppressions précédentes.
Notre objectif est de supprimer toutes les voyelles, qui sont précalculées pour être les indices 1, 4 et 7. Notez que son important les index to_delete sont dans l'ordre croissant, sinon cela ne fonctionnera pas.
Ce serait plus compliqué si vous vouliez supprimer les éléments dans n'importe quel ordre. OMI, le tri
to_delete
pourrait être plus facile que de déterminer quand vous devriez ou ne devriez pas soustraireindex
.la source
Je suis un débutant total en Python, et ma programmation pour le moment est grossière et sale pour le moins, mais ma solution était d'utiliser une combinaison des commandes de base que j'ai apprises dans les premiers tutoriels:
De toute évidence, en raison du choix d'un caractère "marque pour suppression", cela a ses limites.
En ce qui concerne les performances à mesure que la taille de la liste évolue, je suis sûr que ma solution est sous-optimale. Cependant, c'est simple, ce qui j'espère plaira à d'autres débutants, et fonctionnera dans des cas simples où
some_list
est d'un format bien connu, par exemple, toujours numérique ...la source
Voici une alternative, qui n'utilise pas enumerate () pour créer des tuples (comme dans la réponse originale de SilentGhost).
Cela me semble plus lisible. (Peut-être que je me sentirais différemment si j'avais l'habitude d'utiliser enumerate.) CAVEAT: Je n'ai pas testé les performances des deux approches.
REMARQUE: syntaxe Python 2.7. Pour Python 3,
xrange
=>range
.Usage:
une liste:
--- PRIME ---
Supprimez plusieurs valeurs d'une liste. Autrement dit, nous avons les valeurs que nous voulons supprimer:
Usage:
une liste:
C'est la même réponse que précédemment, mais cette fois nous avons fourni les VALEURS à supprimer
[0, 44, 55]
.la source
[ value for (i, value) in enumerate(lst) if i not in set(indices) ]
. Mais je vais laisser ma réponse ici, car je montre également comment supprimer par valeurs. Ce qui est un cas plus facile, mais pourrait aider quelqu'un.indices_as_set = set(indices)
,[ value for (i, value) in enumerate(lst) if i not in indices_as_set ]
pour l' accélérer.delete__by_values()
?Une méthode alternative de compréhension de liste qui utilise des valeurs d'index de liste:
Cela renvoie:
la source
index
étant trompeur car dans l'itérateur de la liste est utilisée la méthodeindex()
voici une autre méthode qui supprime les éléments en place. aussi si votre liste est vraiment longue, elle est plus rapide.
la source
Cela a été mentionné, mais personne n'a réussi à faire les choses correctement.
La
O(n)
solution serait:C'est vraiment proche de la version de SilentGhost , mais ajoute deux accolades.
la source
O(n)
cas si vous comptez les recherches effectuéeslog(len(indices))
pour chaque itération.j not in indices
estO(1)
.j not in indices
nécessite toujours une recherche, ce qui estO(log(len(indices)))
. Bien que je convienne qu'une recherche dans un ensemble de 2 éléments se qualifie commeO(1)
, dans le cas général, ce sera le casO(log(N))
. De toute façonO(N log(N))
bat toujoursO(N^2)
.j not in indices
estO(1)
, sérieusement.C'est fondamentalement la même chose que la réponse la plus votée, juste une manière différente de l'écrire. Notez que l'utilisation de l.index () n'est pas une bonne idée, car elle ne peut pas gérer les éléments dupliqués dans une liste.
la source
La méthode Remove entraînera beaucoup de décalage des éléments de la liste. Je pense qu'il vaut mieux faire une copie:
la source
techniquement, la réponse est NON, il n'est pas possible de supprimer deux objets EN MÊME TEMPS. Cependant, il est possible de supprimer deux objets en une seule ligne de beau python.
supprimera récursivement
foo['bar']
, puisfoo['baz']
la source
nous pouvons le faire en utilisant une boucle for itérant sur les index après avoir trié la liste d'index dans l'ordre décroissant
la source
Pour les indices 0 et 2 de la listeA:
Pour certains indices aléatoires à supprimer de la listeA:
la source
Je voulais un moyen de comparer les différentes solutions qui permettaient de tourner facilement les boutons.
J'ai d'abord généré mes données:
Puis j'ai défini mes fonctions:
Ensuite, je
timeit
comparais les solutions:Production
Donc, le générateur avec les indices dans a
set
était le gagnant. Etdel
c'est légèrement plus rapide alorspop
.la source
Vous pouvez utiliser cette logique:
la source
Une autre implémentation de l'idée de retirer de l'indice le plus élevé.
la source
Je peux en fait penser à deux façons de le faire:
trancher la liste comme (cela supprime les 1er, 3ème et 8ème éléments)
somelist = somelist [1: 2] + somelist [3: 7] + somelist [8:]
faites-le en place, mais un à la fois:
somelist.pop (2) somelist.pop (0)
la source
Vous pouvez le faire sur un dict, pas sur une liste. Dans une liste, les éléments sont en séquence. Dans un dict, ils ne dépendent que de l'index.
Code simple juste pour l'expliquer en faisant :
Une façon de "convertir" une liste dans un dict est:
L'inverse est:
Quoi qu'il en soit, je pense qu'il vaut mieux commencer à supprimer de l'index supérieur comme vous l'avez dit.
la source
Pour généraliser le commentaire de @sth . La suppression d'élément dans n'importe quelle classe, qui implémente abc.MutableSequence , et
list
en particulier, se fait via__delitem__
la méthode magique. Cette méthode fonctionne de la même manière que__getitem__
, ce qui signifie qu'elle peut accepter un entier ou une tranche. Voici un exemple:Cela produira
la source
L'importer uniquement pour cette raison peut être excessif, mais si vous l'utilisez de
pandas
toute façon, la solution est simple et directe:la source
Évite les frais de tri et la copie explicite de la liste
la source
Que diriez-vous de l'un d'entre eux (je suis très nouveau dans Python, mais ils semblent ok):
["Atlantique", "Pacifique", "Indien"]
["Atlantique", "Pacifique", "Indien"]
la source
Aucune des réponses proposées jusqu'à présent n'effectue la suppression en place en O (n) sur la longueur de la liste pour un nombre arbitraire d'indices à supprimer, voici donc ma version:
la source
Vous pouvez également utiliser remove.
la source
Je mets tout cela ensemble dans une
list_diff
fonction qui prend simplement deux listes comme entrées et renvoie leur différence, tout en préservant l'ordre d'origine de la première liste.Exemple d'utilisation:
la source