6
votes

Supprimer une liste d'une liste de listes Python

J'ai une liste de listes:

TypeError: 'list' object cannot be interpreted as an integer

Je souhaite supprimer une sous-liste de la liste si cette sous-liste contient un élément en dehors d'une plage donnée.

Par exemple ; range = 3, 15

Donc, si une sous-liste contient, -69, -17, 0, 1, 2, 15.1, 246.99, c'est-à-dire tout élément qui est en dehors de cette plage, je veux que cette sous-liste soit supprimée.

Le résultat à renvoyer est une liste de listes où toutes les sous-listes contiennent uniquement des valeurs dans cette plage:

max_value = 15
min_value = 3

for sublist in my_list:
  for item in sublist:
    if(item < min_value):
        my_list.pop(sublist)
    if(item > max_value):
        my_list.pop(sublist)
print(my_list)

Je suis conscient qu'il y a questions similaires ici, telles que:

Suppression de sous-listes d'une liste de listes

Python - Supprimer la ou les liste (s) de la liste des listes (fonctionnalité similaire à .pop ())

Je ne parviens pas à faire fonctionner ces solutions.

Mon l'objectif est de ne pas supprimer les doublons de listes: il y a beaucoup de questions à ce sujet mais ce n'est pas mon objectif.

Mon code:

[[6, 5, 7, 13, 12], [4, 6, 10], [9, 9, 4, 5, 11], [4, 4]]

Erreur :

[[0.0,3.3, 4.9, 7.5], [4, 6, 90, 21, 21.1], [3, 43, 99, 909, 2.11, 76, 76.9, 1000]]


4 commentaires

Quelle ligne donne cette erreur? Pourriez-vous publier un retraçage?


il peut s'agir de ma_liste.pop (élément)


Ligne 7, ma_liste.pop (sous-liste). Après la première instruction IF


Il semble que votre exemple soit incohérent. Votre sortie n'est pas liée à votre entrée.


3 Réponses :


4
votes

Votre erreur vient de l'utilisation de la méthode .pop () , qui attend un index entier comme argument, alors que vous voulez vraiment dire .remove () . Cependant, même après avoir corrigé cela en .remove () , vous pouvez également rencontrer des erreurs en essayant de supprimer des éléments d'une liste tout en l'itérant. Une approche plus propre est une compréhension de liste:

my_list = [[0.0,3.3, 4.9, 7.5], [4, 6, 90, 21, 21.1], [3, 43, 99, 909, 2.11, 76, 76.9, 1000]]
min_value = 3
max_value = 100

my_list[:] = [sublist for sublist in my_list if all(min_value <= x <= max_value for x in sublist)]


7 commentaires

Est-ce que all est vraiment nécessaire ici?


@Bazingaa. Quelque chose est-il vraiment nécessaire? Mais sérieusement, all est probablement la meilleure façon de le faire.


@Bazingaa oui. Le sort d'une sous-liste dépend de la conformité de tous ses membres. Ou autrement dit, si un membre n'est pas conforme, la sous-liste entière est sortie.


@MadPhysicist: Je suis heureux de voir l'utilisation de all . Ma question était juste à des fins de curiosité :) Rien contre la réponse. :) J'ai déjà voté pour ça


@jez: Ce que je pensais, c'est que vous utilisez deux boucles for dans votre code alors que vous pouvez en finir avec une. Mais comme je l'ai dit, belle approche +1 car j'ai appris le cas d'utilisation de all


@Bazingaa D'une manière ou d'une autre, vous devez parcourir l'ensemble de chaque sous-liste. Avec min et max , vous faites cela aussi (deux fois en fait) mais probablement plus rapidement en raison de la façon dont ils sont implémentés.


@jez: Roger que :)



1
votes

une compréhension de liste

new_list = [sublist for sublist in list if not any(el in range(a, b) for el in sublist)]


3 commentaires

Qu'attendez-vous que aucun (el dans la sous-liste) fasse?


@MadPhysicist: rien. vient d'appuyer sur Entrée au mauvais moment


cela ne fonctionne que pour les entiers (ce qui est probablement correct), et vous avez peut-être voulu dire range (a, b + 1)



11
votes

Vous pouvez utiliser la compréhension de liste. Voici un exemple d'entrée et de sortie. L'idée est simple: pour chaque sous-liste, il suffit de vérifier les min et max s'ils sortent des limites souhaitées.

list_1 = [[0.0,3.3, 4.9, 7.5], [4, 6, 9, 11, 12.1], [3, 43, 99, 909, 2.11, 76, 76.9, 1000], ]

left = 3
right = 15

list_2 = [i for i in list_1 if (min(i)>=left and max(i)<=right)]
print (list_2)
# [[4, 6, 9, 11, 12.1]]


2 commentaires

Intelligent avec le min et le max. [* filter (lambda x: min (x)> = 3 et max (x) <= 15, list_1)]


@piRSquared: Merci pour le commentaire. :) Votre commentaire est nettement plus concis et moins verbeux