Avec ce code:
>>> strs = ["111", "1000", "1000", "1000"] >>> counts = map(lambda x: [x.count('0'), x.count('1')], strs) >>> list(counts) [[0, 3], [3, 1], [3, 1], [3, 1]] >>> cntSortBy0 = sorted(counts, key=lambda x: x[0]) >>> cntSortBy0 []
Ici, j'ai une liste de chaînes
avec des chaînes comme éléments.
Ensuite, je compte les nombres de ' 0 'et' 1 'respectivement pour chaque chaîne de chaînes et enregistrez les résultats dans count
(je l'ai fait en utilisant map en python3, donc count
est un objet de carte).
Après cela, je trie compte
pour la première fois, et cela fonctionne très bien,
mais quand je trie compte
pour la deuxième fois, cela renvoie une liste vide ( cntSortBy1
est vide),
Je trouve que c'est parce que count
est devenu vide après le premier tri :
>>> strs = ["111", "1000", "1000", "1000"] >>> counts = map(lambda x: [x.count('0'), x.count('1')], strs) >>> cntSortBy0 = sorted(counts, key=lambda x: x[0]) # sort with counts of '0' >>> list(counts) []
Pas étonnant que cntSortBy1
soit vide, mais pourquoi à quelle dose cela se produit?
De plus, si j'imprime simplement liste (comptes)
, cntSortBy1
deviendra également vide, comme indiqué ci-dessous, p >
strs = ["111", "1000", "1000", "1000"] # count the numbers of '0' and '1' respectively for each string in strs counts = map(lambda x: [x.count('0'), x.count('1')], strs) cntSortBy0 = sorted(counts, key=lambda x: x[0]) # sort with counts of '0' cntSortBy1 = sorted(counts, key=lambda x: x[1]) # sort with counts of '1'
Dose cela signifie qu'un objet cartographique ne peut être utilisé qu'une seule fois, après quoi il deviendra une liste vide?
Y a-t-il d'autres objets dans Py3 avec la même fonctionnalité? (J'ai essayé range ()
, ce n'est pas le cas.)
Merci beaucoup !!!
3 Réponses :
En Python3, map
renvoie un itérateur:
https://docs.python.org/3/library/functions.html# map
Et les itérateurs ne peuvent (et devraient) être utilisés qu'une seule fois. Voir la documentation officielle sur les itérateurs: https://docs.python.org/3/tutorial/classes.html# itérateurs
Dans votre cas, vous devez convertir map
en liste
lors de la création, cela résoudra votre problème:
counts = list(map(lambda x: [x.count('0'), x.count('1')], strs))
Ce qui, pour être honnête, serait plus pythonique écrit comme count = [[x.count ('0'), x.count ('1')] for x in strs]
Une fois qu'un itérateur a été épuisé (c'est-à-dire qu'il a été entièrement itéré), il ne reste plus rien à répéter, donc l'itérer une deuxième fois ne donnera rien. Prenons cet exemple.
a = map(int,['1','2','3']) print(sorted(a)) # output: [1, 2, 3] print(sorted(a)) # output: [] a = list(map(int,['1','2','3'])) print(sorted(a)) # output: [1, 2, 3] print(sorted(a)) # output: [1, 2, 3]
Cela affichera:
1 2 3 1 2 3
Chaque fois que vous avez besoin d'itérer plusieurs fois sur un itérateur, transformez-le en liste (ou un autre type de séquence):
a = list(map(int,['1','2','3']))
Ceci génère:
1 2 3
Lors de l'utilisation de sorted () , vous itérez également sur l'objet itérateur
map
:
a = map(int,['1','2','3']) for i in a: print(i) for i in a: print(i)
D'après la documentation: https://docs.python.org/ 3 / library / functions.html # map
carte (fonction, itérable, ...)
/ p>
Renvoie un itérateur qui applique une fonction à chaque élément d'itérable, donnant les résultats.Par conséquent, lorsque vous avez terminé l'itération sur l'itérateur
compte
renvoyé parmap (lambda x: [x.count ('0'), x.count ('1')] , strs)
viatrié (count, key = lambda x: x [0])
, il devient videPour éviter cela, vous devez lancer n'importe quel itérateur vous voulez réutiliser dans une liste en utilisant
list (map (...))
et ensuite vous pouvez l'utiliser autant que vous le souhaitez, par exemple.In [1]: strs = ["111", "1000", "1000", "1000"] In [2]: counts = list(map(lambda x: [x.count('0'), x.count('1')], strs)) In [3]: counts) Out[3]: [[0, 3], [3, 1], [3, 1], [3, 1]] In [4]: cntSortBy0 = sorted(counts, key=lambda x: x[0]) In [5]: cntSortBy0 Out[5]: [[0, 3], [3, 1], [3, 1], [3, 1]] In [6]: counts Out[6]: [[0, 3], [3, 1], [3, 1], [3, 1]] In [7]: cntSortBy1 = sorted(counts, key=lambda x: x[1]) In [9]: cntSortBy1 Out[9]: [[3, 1], [3, 1], [3, 1], [0, 3]] In [10]: counts Out[10]: [[0, 3], [3, 1], [3, 1], [3, 1]]
Au lieu d'une carte, vous pouvez essayer count = [[x.count ('0'), x.count ('1')] for x in strs]