Imprimer une liste dans l'ordre inverse avec range ()?

364

Comment pouvez-vous produire la liste suivante avec range()en Python?

[9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
ramesh.mimit
la source
Qu'en est-il de [* plage (9, -1, -1)]? Super pythonique!
onofricamila

Réponses:

561

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 rangepour 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.

Michał Šrajer
la source
13
Bien qu'il «soit» moins efficace. Et vous ne pouvez pas y trancher.
Jakob Bowyer
6
Cette réponse est très claire et facile à comprendre, mais elle doit l'être 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))).
John Y
5
Cela produit un itérateur, OP a demandé un résultat sous forme de liste.
btk
6
L'utilisation de "inversé" avec le générateur python (en supposant que nous parlons de la gamme Python 3 intégrée) est juste conceptuellement erronée et enseigne de mauvaises habitudes de ne pas prendre en compte la complexité de la mémoire / du traitement lors de la programmation dans un langage de haut niveau.
thedk
7
En Python3, reversedn'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? rangepeut renvoyer un objet qui implémente la __reversed__méthode qui permet une itération inverse efficace?
avmohan
312

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 stopa é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 rangeobjet non-liste , qui fonctionne efficacement comme une liste en lecture seule (mais utilise beaucoup moins de mémoire, en particulier pour les grandes plages).

Mr. B
la source
1
Pouvez-vous s'il vous plaît expliquer cela aussi, pouvez-vous également me recommander n'importe quel site Web / livre pdf pour python
ramesh.mimit
8
@ramesh Si vous exécutez 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)
Michael Mrozek
3
@ ramesh.mimit: Accédez simplement au site officiel de Python. Il y a une documentation complète, y compris un excellent tutoriel.
John Y
5
Vraiment, c'est la bonne réponse, mais cela pourrait être expliqué plus clairement. range(start, stop, step) - commencez par le nombre startet donnez des résultats à moins d' stopavoir été atteints, en vous déplaçant à stepchaque fois.
M. B
43

Vous pouvez utiliser range(10)[::-1]ce qui est la même chose range(9, -1, -1)et sans doute plus lisible (si vous êtes familier avec l' sequence[::-1]idiome Python commun ).

martineau
la source
28

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 .

Loup
la source
3
J'ai fait mes propres synchronisations avant de lire cette réponse et j'ai obtenu les mêmes résultats.
Todd Owen
13
for i in range(8, 0, -1)

va résoudre ce problème. Il affichera 8 à 1, et -1 signifie une liste inversée

Jutta
la source
10

Aucun sens à utiliser reversecar 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 stepet le définir -1, les autres paramètres doivent être ajustés en conséquence:

  1. Fournir arrêt paramètre comme -1(sa valeur précédente stop - 1, stopétait égal à 0).
  2. En tant que paramètre de démarrage, utilisez 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]
Andriy Ivaneyko
la source
6
Franchement, je trouve cela moins intuitif quereversed(range(n))
Nicholas Hamilton
1
@NicholasHamilton D'accord avec vous, mais l'idée derrière cette réponse est d'utiliser moins de ressources ... (et la question portait sur l'utilisation de la fonction de plage juste :))
Andriy Ivaneyko
Ok, pas de soucis, je suppose que cela dépend de la situation. Par exemple, si la fonction de plage est utilisée comme index pour une boucle, alors elle aura un effet limité, cependant, si elle est utilisée à l'intérieur d'une boucle externe, alors le coût sera composé ...
Nicholas Hamilton
8

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 :)

Jaime RGP
la source
bon d'avoir quelques chiffres :) - pourquoi n'avez-vous pas ajouté range(1000000000-1,-1,-1)aussi?
Wolf
... mieux vaut ne pas essayer timeit range(1000000000-1,-1,-1)sur la ligne de commande, voir plutôt mes résultats :-)
Wolf
6

L'exigence de cette question appelle un nombre listentier 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]
un33k
la source
2
J'aime vraiment le triple-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.
Wolf
5

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

M. Suryaa Jha
la source
5

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:

  1. Soit la prise en charge len()et les index entiers via[]
  2. Ou avoir __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.

Shital Shah
la source
3

je crois que cela peut aider,

range(5)[::-1]

ci-dessous est Utilisation:

for i in range(5)[::-1]:
    print i 
dineshsprabu
la source
3
range(9,-1,-1)
[9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
Asinox
la source
13
Votre réponse montre pourquoi reversed(range(10))est moins sujet aux erreurs. Pas d'infraction Asinox. Juste une observation honnête.
Michał Šrajer
Je ne sais pas s'il est normal de laisser des réponses erronées affichées. Puis-je ou quelqu'un le corriger ou même le supprimer?
sinekonata
3
@sine, non, laissez-le simplement et demandez-vous comment il a accumulé 3 votes positifs ... Je suppose que vous pouvez le signaler à l'attention du modérateur (duplicata de la réponse de 18 mois plus tôt sauf cassé), pas sûr qu'ils le suppriment ou non.
OGHaza
Pour toute référence future: seul le code n'est pas VLQ , et les mauvaises réponses ne sont pas censées être signalées non plus . Votez et continuez, mais le signalement est incorrect dans ce cas, que ce soit NAA ou mod-flagging. - De l'avis
Zoe
2

Utilisation sans [:: - 1] ou inversé -

def reverse(text):
    result = []
    for index in range(len(text)-1,-1,-1):
        c = text[index]
        result.append(c)
    return ''.join(result)

print reverse("python!")
rhel.user
la source
6
Pourquoi quelqu'un devrait-il écrire cela au lieu de "python!"[::-1]?
Daniel
1
[9-i for i in range(10)]
[9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
Jason
la source
1

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.

user7420740
la source
Cela semble être la solution suggérée dans une réponse précédente . Il semble également que vous essayiez de commenter une réponse précédente différente - vous devrez obtenir un peu plus de réputation avant de pouvoir le faire.
Grisha Levit
1

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.

Vishal Kumar
la source
0
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.

user3807372
la source
0

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))

Réponse de Jason :

%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)

réponse de martineau :

%timeit a[::-1]
135 ns ± 4.07 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)

Réponse de Michał Šrajer :

%timeit list(reversed(a))
374 ns ± 9.87 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)

réponse de bene :

%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.timeitsous le capot. Testé pour Python 3.7.3

pkuderov
la source