J'ai une liste avec n éléments:
['pea', 'rpai', 'rpai', 'schiai', 'pea', 'rpe', 'zoi', 'zoi', 'briai', 'rpe'] [ 0, 1, 1, 2, 0, 3, 4, 4, 5, 3 ]
Je dois attribuer un numéro à chaque chaîne, zéro au début, puis incrémenter de un si l'élément est différent, donner à la place le même numéro si l'élément se répète. Exemple:
['pea', 'rpai', 'rpai', 'schiai', 'pea', 'rpe', 'zoi', 'zoi', 'briai', 'rpe']
Comment puis-je le faire?
7 Réponses :
Essaye ça:
a = ['pea', 'rpai', 'rpai', 'schiai', 'pea', 'rpe', 'zoi', 'zoi', 'briai', 'rpe'] dct = {} counter = 0 for i in range(len(a)): if a[i] not in dct.keys(): dct[a[i]] = counter counter += 1 print([(i, dct[i]) for i in a])
Pourquoi le +1? Cela ne produit pas ce que le PO a demandé.
Vous avez juste besoin de prouver si vous l'aviez déjà
def counts(final): count3 = [] # contains all objects that were already found count2=[] count=0 for x in final: if x not in count3: # test if it's not already in count3 count+=1 count2.append(count) count3.append(x) else: count2.append(count) return count2
Votre solution renvoie [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
pour les données d'exemple, pas la sortie attendue. Vous n'ajoutez jamais quelque chose à count3
pour tester si vous avez déjà vu l'élément.
Maintenant, il renvoie [1, 2, 3, 4, 5, 6]
.
Ouais. Pourquoi le +1 à ce sujet. Les gens regardent simplement n'importe quel code qui est jeté comme réponse et dit "bien sûr, c'est génial!" sans le lire ou l'essayer?
[1, 2, 2, 3, 3, 4, 5, 5, 6, 6]
Je ne teste pas davantage votre code. Il existe déjà des solutions correctes.
Je ne peux pas croire combien de personnes publient un code sans prendre la peine de l'essayer, surtout lorsque l'OP a donné le résultat exact auquel elles s'attendent.
Ouais sais je sais, ça ne donne pas le résultat que j'aurais aimé donner, mais je ne connaissais pas les autres approches
Mais alors pourquoi l'avez-vous posté comme réponse? Comment cela aide-t-il quelqu'un?
l'utilisation d'un dictionnaire permettrait d'atteindre cet objectif.
def counts(a): dis = {} count=0 for i in range(len(a)): if a[i] not in dis.keys(): dis[a[i]] = count count+=1 return([dis[x] for x in a])
Hey! Une réponse qui donne réellement le résultat demandé!
Je crois que for i, _ in enumerate(a)
est plus pythonique que for i in range(len(a))
. Mais vous n'utilisez jamais que i
dans a[i]
, auquel cas il est plus logique de juste for x in a
et d'utiliser x
au lieu de a[i]
.
@BernhardBarker est d'accord
Avec un assistant dict:
>>> d = {} >>> [d.setdefault(x, len(d)) for x in final] [0, 1, 1, 2, 0, 3, 4, 4, 5, 3]
Autrement:
>>> [*map({k: v for v, k in enumerate(dict.fromkeys(final))}.get, final)] [0, 1, 1, 2, 0, 3, 4, 4, 5, 3]
@superb rain, merci pour la deuxième option. C'est tellement génial et cela crache les valeurs directement dans la liste tout en les affectant au dictionnaire.
Si quelqu'un est assez nouveau dans la programmation pour ne pas savoir comment faire ce qui est demandé dans la question, je doute fort qu'il soit capable de comprendre ces complexes one-liners.
Je me suis trompé et je dois utiliser un dictionnaire (merci @Steve). Voici la version mise à jour avec dictionnaire inclus:
['pea', 'rpai', 'rpai', 'schiai', 'pea', 'rpe', 'zoi', 'zoi', 'briai', 'rpe'] [0, 1, 1, 2, 0, 3, 4, 4, 5, 3]
Le résultat de ceci sera:
a = ['pea', 'rpai', 'rpai', 'schiai', 'pea', 'rpe', 'zoi', 'zoi', 'briai', 'rpe'] b = [None]*len(a) d = {} for i,x in enumerate(a): if x not in d: d[x] = len (d) #or use d.setdefault(x, len(d)) instead of the if statement (using the algo from @superb rain's) b[i] = d[x] print (a) print (b)
Eh bien, d'abord, la réponse est fausse. Deuxièmement, la raison d'utiliser un dictionnaire est que vous n'avez pas à chercher à plusieurs reprises dans la liste, ce que fait votre code. Donc, votre code est inefficace ... mais il évite l'utilisation d'un dictionnaire.
Merci d'avoir lu mon code. Je l'ai mis à jour avec du code en utilisant le dictionnaire
Bien mieux. Il y a cependant un gros correctif que vous devriez faire. Quand vous faites if x not in d.keys()
vs if x not in d
, vous effacez toute la raison d'utiliser un dictionnaire. Vous extrayez toute la liste des clés du dictionnaire, ce qui prend du temps. Ensuite, vous effectuez une recherche linéaire dans cette liste. Tout cela au lieu de rechercher directement la valeur dans le dictionnaire, ce à quoi les dictionnaires sont bons.
Merci pour l'explication. Je comprends maintenant. Je n'ai pas réalisé l'importance de d vs d.keys ()
@Steve Vous pensez donc que nous utilisons toujours Python 2? Même s'il est officiellement mort?
@superbrain - désolé. Je ne te suis pas. - ai-je utilisé une instruction d'impression sans parenthèses quelque part?, lol
@Steve En Python 3, d.keys()
ne retourne pas une liste mais une vue , et cela prend O (1) espace et temps.
Ha! Oh vraiment? ok, je me suis trompé alors. J'étais, en fait, l'un des derniers résistants au passage de Python 2. À ce jour, j'apprends (évidemment) toujours ce qui a changé à propos de P3. Merci de m'avoir corrigé. Désolé @JoeFerndz, je suppose que je vous ai trompé. Y a-t-il un inconvénient à x in d
vs x in d.keys()
. Je me demandais simplement combien de dégâts je devais infliger si Superb n'avait pas attrapé cela.
@Steve Pour un test d'appartenance, x in d
est le bon moyen, x in d.keys()
est inutile et plus lent (mais pas aussi mauvais que vous le pensiez :-). La vue qu'il vous donne peut être bénéfique si vous en avez l'habitude pour son comportement de jeu.
Je viens de lire Quoi de neuf dans P 3.0 , ne voulant pas refaire une erreur similaire. Le d.keys()
est le problème n ° 2 répertorié sous "Gotchas", juste après la modification à print
. Je suis surpris de ne pas avoir encore choisi celui-ci. Merci encore Superbrain!
Je suis content d'avoir commis l'erreur. J'ai beaucoup appris de cette erreur et de cette conversation. Merci à tous les deux Steve & Suberb Rain.
Utilisez un defaultdict et utilisez un compteur comme fonction de valeur par défaut.
Chaque fois que la clé existe, elle renvoie la "première position rencontrée" stockée, sinon elle appelle Incr.__call__
qui incrémente son décompte pour fournir une nouvelle première position rencontrée.
Avec la suggestion de super brain, utilisez une contre-classe existante:
[0, 1, 1, 2, 0, 3, 4, 4, 5, 3]
Lancer mon propre Incr, comme avant, ce qui vous donne l'avantage de pouvoir renvoyer n'importe quoi (comme un GUID):
from collections import defaultdict class Incr: def __init__(self): self.count = -1 def __call__(self): self.count +=1 return self.count li = ['pea', 'rpai', 'rpai', 'schiai', 'pea', 'rpe', 'zoi', 'zoi', 'briai', 'rpe'] seen = defaultdict(Incr()) print( [seen[val] for val in li] )
from collections import defaultdict from itertools import count li = ['pea', 'rpai', 'rpai', 'schiai', 'pea', 'rpe', 'zoi', 'zoi', 'briai', 'rpe'] seen = defaultdict(count().__next__) print( [seen[val] for val in li] )
Peut également utiliser itertools.count().__next__
ou seen.__len__
ou lambda: len(seen)
comme usine par défaut.
@superbrain itertools.count () .__ next__ pourrait être une bonne solution. à vrai dire, je trouve votre truc de len (dict) impressionnant. mais c'est un peu trop astucieux, le genre de chose où ce qui se passe n'est pas assez évident, 6 mois plus tard. mais c'est certainement une bonne réflexion.
La manière la plus propre pourrait être d'utiliser des pandas:
(array([0, 1, 1, 2, 0, 3, 4, 4, 5, 3], dtype=int64), array(['pea', 'rpai', 'schiai', 'rpe', 'zoi', 'briai'], dtype=object))
Quelles sorties:
import pandas as pd lst = ['pea', 'rpai', 'rpai', 'schiai', 'pea', 'rpe', 'zoi', 'zoi', 'briai', 'rpe'] pd.factorize(lst)
Veuillez mettre à jour votre question avec le code que vous avez essayé.
Ce code n'est pas correctement mis en retrait. On ne sait pas ce
count2
devraient êtrecount
etcount2
et pourquoi ils ont des types différents. Pouvez-vous nous le dire dans un langage normal? Il n'y a pas de condition qui fasse une distinction entre un élément répétitif et non répétitif, donc on s'attend à ce que ce code ne fonctionne pas. De plus, veuillez fournir un exemple reproductible minimal , avec tous les codes et exemples de données en ligne. Enfin, en tant que nouvel utilisateur ici, faites le tour et lisez Comment demander .Vous ne vérifiez jamais que l'élément se répète.
Mon conseil serait de vous asseoir avec votre professeur ou un tuteur ou un camarade de classe qui pourra vous guider dans la bonne direction. Le fait de vous donner la réponse aiderait à résoudre votre problème immédiat, mais cela ne vous apprendrait pas à réfléchir et à résoudre les problèmes, ce qui est une partie fondamentale de la programmation. Vous allez probablement rencontrer des problèmes similaires avec le prochain problème de devoirs. Le cours devrait également s'appuyer sur des concepts antérieurs au fur et à mesure que le cours progresse, de sorte que les problèmes ultérieurs seraient beaucoup plus difficiles que les précédents si vous ne résolviez pas les premiers vous-même.
Consultez également Python Map List of Strings to Integer List , Python: comment convertir un tableau de chaînes en liste de facteurs .