efficacement la vérification de cette chaîne se compose d'un personnage dans Python
Ce qui est un moyen efficace pour vérifier qu'une chaîne de caractères s
en Python se compose d'un seul caractère, disons 'A'
? Quelque chose comme all_equal(s, 'A')
qui se comporte comme ceci:
all_equal("AAAAA", "A") = True
all_equal("AAAAAAAAAAA", "A") = True
all_equal("AAAAAfAAAAA", "A") = False
Deux apparemment inefficace, seraient les suivants: d'abord convertir la chaîne en une liste et vérifier chaque élément, ou de seconde pour utiliser une expression régulière. Existe-il des moyens plus efficaces ou sont-ils les meilleurs, on peut le faire en Python? Merci.
- Je suis un peu surpris pas encore posé la question suivante: qu'est-ce que la structure de la "non uniforme" les chaînes de la saisie? Si il y en a un (c'est à dire qu'ils ne sont pas complètement au hasard), vous pouvez utiliser les connaissances à ce sujet pour optimiser votre algorithme.
- L'efficacité de ce vraiment important? Je me demande quel genre d'application aurait cette vérification dans le goulot d'étranglement de code.
- À mon avis, l'efficacité de la que rarement, il peut être important, mais qui sait? De toute façon, la tâche est agréable, et la compréhension de ce qui se passe à l'intérieur du code, et pourquoi certaines solutions sont lents, et certains sont rapides, est une formation utile pour un développeur Python.
Vous devez vous connecter pour publier un commentaire.
C'est de loin le plus rapide, plusieurs fois plus rapide que même
count()
, juste le temps avec cet excellent mgilson moment suite:Ici tous la vérification se fait à l'intérieur de l'Python code C qui vient:
Plus la série est longue, plus grande est des bonus de temps. Cependant, comme mgilson écrit, il crée une copie de la chaîne, donc si votre chaîne est de longueur plusieurs millions de signes, il peut devenir un problème.
Comme on peut le voir à partir des résultats de minutage, généralement des moyens les plus rapides pour résoudre la tâche de ne pas exécuter n'importe quel code Python pour chaque symbole. Cependant, la
set()
solution aussi fait tout le travail à l'intérieur C le code de la bibliothèque Python, mais il est encore lent, probablement en raison de l'exploitation de la chaîne par le biais de Python interface d'un objet.UPD: Concernant la chaîne vide en cas. Quoi faire avec elle, dépend fortement de la tâche. Si la tâche est de "vérifier si tous les symboles en une chaîne de caractères sont les mêmes",
s == len(s) * s[0]
est une réponse valide (pas de symboles signifient une erreur, et l'exception est ok). Si la tâche est de "vérifier si il y a exactement un symbole unique", une chaîne vide devrait nous donner de Faux, et la réponse ests and s == len(s) * s[0]
, oubool(s) and s == len(s) * s[0]
si vous préférez recevoir des valeurs booléennes. Enfin, si nous comprenons la tâche comme "vérifier si il n'y a pas de symboles", le résultat pour la chaîne vide est Vrai, et la réponse estnot s or s == len(s) * s[0]
.count
devrait être une simple boucle qui ferait environ la même quantité de travail que le remplissage de l'espace permettrait de le faire. Je suppose que le remplissage est probablement fait par le biais de certaines impressionnant vectorisé/code optimisé dans le C de la bibliothèque string. (Comme c'est la comparaison qui peut être court-circuitée).count
pourrait fonctionner sur les cordes avec plus de longueur que de 1 :). Je suis bête.s == len(s) * c[0]
comme il me sembles == len(s) * s[0]
juste des tests qu'une chaîne est composée d'un même caractère. Alors qu'à l'origine de l'OP était ce qui implique qu'il y avait 2 variables s(tring) à tester et (c)du caractère à vérifier.Ce n'est pas de court-circuit. Une version qui ne court-circuit:
Cependant, j'ai le sentiment qu'en raison de la l'C optimisés mise en œuvre, la non-court-circuit version sera probablement plus performant sur certaines chaînes (en fonction de la taille, etc)
Ici est un simple
timeit
script pour tester quelques-uns des autres options posté le:Sur ma machine (OS X 10.5.8, core2duo, python2.7.3) avec ces artificiel (court) les chaînes de caractères,
str.count
fumeset
etall
, et batstr.replace
par un peu, mais il est devancé parstr.translate
etstrmul
est actuellement en tête par une bonne marge:Le timing risque d'être un peu (ou même de manière significative?) différents entre les différents systèmes et différentes chaînes, alors que ce serait intéressant de regarder dans une chaîne de caractères que vous avez l'intention de passer.
Finalement, si vous frappez le meilleur des cas pour
all
assez, et vos chaînes sont assez longtemps, vous pourriez envisager qu'un. C'est un meilleur algorithme ... je voudrais éviter lesset
solution mais comme je ne vois pas de cas où il pourrait battre lacount
solution.Si la mémoire pourrait être un problème, vous aurez besoin pour éviter
str.translate
,str.replace
etstrmul
que ceux de créer une deuxième chaîne, mais ce n'est pas un sujet de préoccupation ces jours-ci.^(.)\1*$
comparer?re.match('^(1)\1*$', s)
.Vous pouvez convertir à un ensemble et vérifier qu'il n'y est qu'un seul membre:
Essayez d'utiliser la fonction intégrée
all
:is
est effectivement plus rapide, stackoverflow.com/a/14321001/1561176is
est en s'appuyant sur unCpython
détail d'implémentation.is
.is
est garanti pour fonctionner. Elle s'appuie sur un détail de l'implémentation de l'interprète, à savoir un stage de cordes, qui n'est pas garanti selon le Python spec autant que je me souvienne. Oui, il sera probablement de travail partout au moins pour de courtes chaînes, mais "probablement" n'est pas vraiment la meilleure chose à compter.all
Ajoutant une autre solution à ce problème
translate
est gagnant dans mes timings ... (mais pas de beaucoup) (+1).s == s[0]*len(s)
🙂Si vous avez besoin de vérifier si tous les caractères de la chaîne sont les mêmes et est égale à un personnage donné, vous devez supprimer tous les doublons et de vérifier si le résultat final est égal au caractère unique.
Dans le cas où vous souhaitez déterminer s'il existe un double, il suffit de cocher la longueur
Intéressant de réponses. Voici un autre:
Le seul avantage que je peux penser à la mienne, c'est qu'il n'est pas nécessaire de parcourir l'ensemble de la chaîne si elle trouve un caractère incohérent.
all
fait aussi bien. une fois qu'il trouve une valeur qui est faux, il s'arrête.timeit