Comment pouvez-vous produire la liste suivante avec range()
en Python?
[9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
Comment pouvez-vous produire la liste suivante avec range()
en Python?
[9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
Réponses:
utiliser la reversed()
fonction:
reversed(range(10))
C'est beaucoup plus significatif.
Mise à jour:
Si vous voulez que ce soit une liste (comme l'a souligné btk):
list(reversed(range(10)))
Mise à jour:
Si vous souhaitez utiliser uniquement range
pour obtenir le même résultat, vous pouvez utiliser tous ses paramètres.range(start, stop, step)
Par exemple, pour générer une liste [5,4,3,2,1,0]
, vous pouvez utiliser les éléments suivants:
range(5, -1, -1)
C'est peut-être moins intuitif mais comme les commentaires le mentionnent, c'est plus efficace et la bonne utilisation de la plage pour la liste inversée.
range(10)
, non range(9)
. De plus, si vous voulez une liste complète (pour le découpage, etc.), vous devriez le faire list(reversed(range(10)))
.
reversed
n'accepte pas les générateurs en général mais il accepte range
. Pourquoi aurait-il reversed(range(10000))
besoin d'allouer de la mémoire à toute la liste? range
peut renvoyer un objet qui implémente la __reversed__
méthode qui permet une itération inverse efficace?
Utilisez la fonction intégrée «gamme». La signature est range(start, stop, step)
. Cela produit une séquence qui donne des nombres, commençant par start
, et se terminant si stop
a été atteint, à l'exclusion stop
.
>>> range(9,-1,-1)
[9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
>>> range(-2, 6, 2)
[-2, 0, 2, 4]
En Python 3, cela produit un range
objet non-liste , qui fonctionne efficacement comme une liste en lecture seule (mais utilise beaucoup moins de mémoire, en particulier pour les grandes plages).
help(range)
dans un shell python, il vous indiquera les arguments. Ils sont le nombre pour commencer, le nombre pour terminer (exclusif) et l'étape à prendre, donc il commence à 9 et soustrait 1 jusqu'à ce qu'il atteigne -1 (à quel moment il s'arrête sans revenir, c'est pourquoi la plage se termine à 0)
range(start, stop, step)
- commencez par le nombre start
et donnez des résultats à moins d' stop
avoir été atteints, en vous déplaçant à step
chaque fois.
Pour ceux qui sont intéressés par "l'efficacité" des options collectées jusqu'à présent ...
La réponse de Jaime RGP m'a amené à redémarrer mon ordinateur après avoir chronométré la solution quelque peu "difficile" de Jason suivant littéralement ma propre suggestion (via un commentaire). Pour épargner aux curieux d'entre vous les temps d'arrêt, je vous présente ici mes résultats (les pires-premiers):
Réponse de Jason (peut-être juste une excursion dans le pouvoir de la compréhension de liste ):
$ python -m timeit "[9-i for i in range(10)]"
1000000 loops, best of 3: 1.54 usec per loop
réponse de martineau (lisible si vous connaissez la syntaxe des tranches étendues ):
$ python -m timeit "range(10)[::-1]"
1000000 loops, best of 3: 0.743 usec per loop
Réponse de Michał Šrajer (celle acceptée, très lisible):
$ python -m timeit "reversed(range(10))"
1000000 loops, best of 3: 0.538 usec per loop
réponse de bene (la toute première, mais très sommaire à l'époque ):
$ python -m timeit "range(9,-1,-1)"
1000000 loops, best of 3: 0.401 usec per loop
La dernière option est facile à retenir en utilisant la range(n-1,-1,-1)
notation de Val Neekman .
reverse
car la méthode range peut retourner une liste inversée.Lorsque vous avez une itération sur n éléments et que vous souhaitez remplacer l'ordre de liste renvoyé par range(start, stop, step)
vous devez utiliser le troisième paramètre de la plage qui l'identifie step
et le définir -1
, les autres paramètres doivent être ajustés en conséquence:
-1
(sa valeur précédente stop - 1
, stop
était égal à 0
).n-1
.Donc, l'équivalent de la plage (n) dans l'ordre inverse serait:
n = 10
print range(n-1,-1,-1)
#[9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
reversed(range(n))
La lisibilité mise à part, reversed(range(n))
semble être plus rapide que range(n)[::-1]
.
$ python -m timeit "reversed(range(1000000000))"
1000000 loops, best of 3: 0.598 usec per loop
$ python -m timeit "range(1000000000)[::-1]"
1000000 loops, best of 3: 0.945 usec per loop
Juste si quelqu'un se demandait :)
range(1000000000-1,-1,-1)
aussi?
timeit range(1000000000-1,-1,-1)
sur la ligne de commande, voir plutôt mes résultats :-)
L'exigence de cette question appelle un nombre list
entier de taille 10 dans l'ordre décroissant. Produisons donc une liste en python.
# This meets the requirement.
# But it is a bit harder to wrap one's head around this. right?
>>> range(10-1, -1, -1)
[9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
# let's find something that is a bit more self-explanatory. Sounds good?
# ----------------------------------------------------
# This returns a list in ascending order.
# Opposite of what the requirement called for.
>>> range(10)
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
# This returns an iterator in descending order.
# Doesn't meet the requirement as it is not a list.
>>> reversed(range(10))
<listreverseiterator object at 0x10e14e090>
# This returns a list in descending order and meets the requirement
>>> list(reversed(range(10)))
[9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
-1
C'est exactement ce modèle qui le rend facile à conserver wrap one's head around this
- Aujourd'hui, j'ai appris que s'il doit vraiment être efficace , utilisez-le range(n-1, -1, -1)
lorsque vous parcourez une plage dans l'ordre inverse.
Vous pouvez imprimer des nombres inversés avec range () BIF Like,
for number in range ( 10 , 0 , -1 ) :
print ( number )
La production sera [10,9,8,7,6,5,4,3,2,1]
range () - plage (début, fin, incrément / décrément) où début est inclusif, fin est exclusif et incrémenter peut être n'importe quel nombre et se comporte comme pas
Très souvent, la question est de savoir si range(9, -1, -1)
mieux qu'en reversed(range(10))
Python 3? Les personnes qui ont travaillé dans d'autres langues avec des itérateurs ont immédiatement tendance à penser que reverse () doit mettre en cache toutes les valeurs, puis revenir dans l'ordre inverse. Le fait est que l' reversed()
opérateur de Python ne fonctionne pas si l'objet n'est qu'un itérateur. L'objet doit avoir l'un des deux suivants pour que reverse () fonctionne:
len()
et les index entiers via[]
__reversed__()
implémenté la méthode.Si vous essayez d'utiliser reverse () sur un objet qui n'a rien de ci-dessus, vous obtiendrez:
>>> [reversed((x for x in range(10)))]
TypeError: 'generator' object is not reversible
Donc, en bref, Python reversed()
est uniquement destiné aux objets de type tableau et devrait donc avoir les mêmes performances que l'itération directe.
Mais qu'en est-il range()
? N'est-ce pas un générateur? En Python 3, il est générateur mais enveloppé dans une classe qui implémente les deux ci-dessus. range(100000)
Ne prend donc pas beaucoup de mémoire, mais il prend toujours en charge l'indexation et l'inversion efficaces.
Donc, en résumé, vous pouvez utiliser reversed(range(10))
sans aucun impact sur les performances.
je crois que cela peut aider,
range(5)[::-1]
ci-dessous est Utilisation:
for i in range(5)[::-1]:
print i
range(9,-1,-1)
[9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
reversed(range(10))
est moins sujet aux erreurs. Pas d'infraction Asinox. Juste une observation honnête.
Vous n'avez pas nécessairement besoin d'utiliser la fonction range, vous pouvez simplement faire list [:: - 1] qui devrait retourner rapidement la liste dans l'ordre inverse, sans utiliser d'ajouts.
Supposons que vous ayez une liste appelez-la a = {1,2,3,4,5} Maintenant, si vous voulez imprimer la liste en sens inverse, utilisez simplement le code suivant.
a.reverse
for i in a:
print(i)
Je sais que vous avez demandé à l'aide de la plage, mais il a déjà répondu.
range(9,-1,-1)
[9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
Est la bonne forme. Si tu utilises
reversed(range(10))
vous n'obtiendrez pas un cas 0. Par exemple, supposons que votre 10 n'est pas un nombre magique et qu'une variable que vous utilisez pour rechercher commence à l'envers. Si votre cas n est 0, inversé (plage (0)) ne s'exécutera pas, ce qui est faux si vous avez par hasard un seul objet dans l'index zéro.
Je pensais que beaucoup (comme moi) pourraient être plus intéressés par un cas courant de traverser une liste existante dans un ordre inversé à la place, comme cela est indiqué dans le titre, plutôt que de simplement générer des indices pour une telle traversée.
Même si toutes les bonnes réponses sont toujours parfaitement correctes dans ce cas, je tiens à souligner que la comparaison des performances effectuée dans la réponse de Wolf concerne uniquement la génération d'indices. J'ai donc fait un benchmark similaire pour parcourir une liste existante dans l'ordre inverse.
TL; DR a[::-1]
est le plus rapide.
Conditions préalables:
a = list(range(10))
%timeit [a[9-i] for i in range(10)]
1.27 µs ± 61.5 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
%timeit a[::-1]
135 ns ± 4.07 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)
%timeit list(reversed(a))
374 ns ± 9.87 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
%timeit [a[i] for i in range(9, -1, -1)]
1.09 µs ± 11.1 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
Comme vous le voyez, dans ce cas, il n'est pas nécessaire de générer explicitement des indices, donc la méthode la plus rapide est celle qui fait le moins d'actions supplémentaires.
NB: J'ai testé dans JupyterLab qui a une "commande magique" pratique %timeit
. Il utilise standard timeit.timeit
sous le capot. Testé pour Python 3.7.3