Python vérifier si tous les éléments d'une liste sont du même type
Comment est-ce possible en python pour vérifier (sans vérifier individuellement chaque élément si possible) si les éléments d'une liste sont du même type?
Par exemple, je voudrais avoir une fonction pour vérifier que chaque élément de cette liste est de type entier (ce qui est clairement faux):
x=[1, 2.5, 'a']
def checkIntegers(x):
# return true if all elements are integers, false otherwise
- Comment pourriez-vous le faire sans vérification de chaque élément? Il n'y a aucun moyen de savoir quelque chose sur un élément que vous n'avez pas regardé.
- vous pouvez court-circuit dès que vous trouvez une mauvaise.
- Semble que l'utilisation de
all
est le chemin... - oui... j'ai pensé que l'OP a demandé une solution qui n'implique pas de l'itération à tous.
InformationsquelleAutor linello | 2012-11-06
Vous devez vous connecter pour publier un commentaire.
Essayez d'utiliser
all
en conjonction avecisinstance
:Vous pouvez même vérifier plusieurs types avec
isinstance
si c'est souhaitable:Pas que ce sera de recueillir les classes héritées ainsi. par exemple:
Si vous besoin de vous limiter à seulement entiers, vous pouvez utiliser
all(type(x) is int for x in lst)
. Mais c'est un TRÈS rares.Un plaisir de fonction vous pouvez écrire avec de c'est l'un qui renvoie le type du premier élément dans une séquence si tous les autres éléments sont du même type:
Cela fonctionne pour n'importe quel itérable, mais il va consommer "itérateurs" dans le processus.
Plaisir un autre fonction de la même veine qui renvoie l'ensemble des bases communes:
homogeneous_type()
(je suppose que c'est ce que la fonction est censé être appelé) erreurs pour vider les itérateurs. En outre, le résultat dépend de l'ordre des éléments dans l'itérable (je suppose que c'est ce que vous entendez par "itérateur"), ce qui n'est pas ce que je m'attends à partir d'une fonction de ce nom. (Un exemple serait[0, False]
et[False, 0]
.)[0, False]
ou[False, 0]
, j' pourrait résoudre qu'en faisantall( type(x) is first_type for x in iseq )
, mais il me semble que la fonction serait plus utile s'il vérifié OK pour les sous-classes ainsi.iterable
. Pour la sémantique, quels termes utiliseriez-vous pour décrire iterables qui peut être consommée (iter(...)
ou générateurs) vs iterables qui ne le peuvent pas (list
,tuple
, ...)? (Et merci pour regarder à cette critique. Espérons que ça va faire pour une meilleure réponse 🙂all()
a aussi l'avantage dans le fait qu'elle court-circuit et de s'arrêter dès qu'il rencontre unFalse
valeur à partir du générateur d'expression.x
être l'objet de liste?all
retourneTrue
vide itératif, qui est pourquoihomogeneous_type
travaille pour des séquences de longueur 1. Astucieux!À l'aide de
any()
, pas besoin de parcourir toute la liste. Juste en pause dès que l'objet qui n'est pasint
oulong
est trouvé:all
, mais je suppose quenot any(not condition ...)
travaille trop. +1 pour vos efforts, je suppose (et pour démontrerall
's de contrepartie, ce qui est tout aussi utile.)all()
en fonction de la solution.all
aussi les courts-circuits, donc il n'y a pas vraiment de différence entre le présent et @mgilson de la solution. C'est plus un exercice de logique...any(not isinstance(e,type(seq[0])) for e in seq[1:])
seq
de cours. Sinon, vous devez utiliseriter
etnext
-- ce Qui vous permet d'économiser les frais généraux de fabrication d'une copie, mais c'est généralement assez bon marché pour les listes.%timeit all(isinstance(x, basestring) for x in list_w_int_or_str)
prend moins de temps que%timeit not any(not isinstance(x, basestring) for x in list_w_int_or_str)
isinstance()
doit être préférée à l'type()
.isinstance()
outype()
?isinstance(i,(int,long))
serait de travailler à la place.isinstance(i,(int,long))
est court. ce n'est pas une question de vitesse, de type() échouera pour les sous-classes d'intLa façon la plus simple pour vérifier si une liste est composée de omogeneous éléments peuvent être à l'égard du groupe de la fonction du module itertools:
Si le th len est différent de celui qu'il signifie qu'il a trouvé de différents types dans la liste.
C'est le problème de l'exécution par l'ensemble de la séquence.
Si vous voulez un paresseux version, vous pouvez écrire une fonction pour ça:
Cette fonction stocker le type du premier élément et arrêter dès qu'elle trouve un autre type dans l'un des éléments dans la liste.
Deux de ces méthodes sont fortement sensible à la nature, donc il va voir que différentes int et float, mais ce doit être aussi proche que vous pouvez obtenir à votre demande
EDIT:
remplacé le pour le cycle avec un appel à tous, comme suggéré par mgilson
en cas de vide itérateur elle renvoie True pour être cohérent avec le comportement de la bulitin toutes les fonctions
any()
, voir ma solution.a=iter(obj);t=type(next(a));all(isinstance(x,t) for x in a)
. C'est encore plus facile pour une liste qui est ce que la question est à propos --t = type(lst[0]); return all(instance(x,t) for x in lst[1:])
. Pas trop mal.lambda i: type(i)
, vous pouvez simplement utilisertype
.Combinant certaines des réponses déjà données, en utilisant une combinaison de carte(), le type() et set() fournit un à mon humble avis plutôt lisible réponse. En supposant que la limite de ne pas vérifier le type de polymorphismes est ok. Également pas les plus efficaces de calcul de réponse, mais il permet de facilement vérifier si tous les éléments sont du même type.
Vous pouvez également utiliser
type()
si vous souhaitez exclure des sous-classes. Voir la différence entreisinstance()
ettype()
:Bien que vous ne voulez pas, parce que ce sera de plus en plus fragile. Si y change son type d'une sous-classe de type int, ce code va briser, alors que
isinstance()
fonctionne toujours.C'est OK pour utiliser
is
car il n'est qu'un<type 'int'>
en mémoire, de sorte qu'ils doivent retourner le même identité s'ils sont du même type.Je préfère utiliser la carte pour un cas comme celui-ci: