Eine Liste in umgekehrter Reihenfolge mit range () drucken?

364

Wie können Sie die folgende Liste range()in Python erstellen ?

[9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
ramesh.mimit
quelle
Was ist mit [* Bereich (9, -1, -1)]? Super pythonisch!
Onofricamila

Antworten:

561

verwenden reversed()Funktion:

reversed(range(10))

Es ist viel sinnvoller.

Aktualisieren:

Wenn Sie möchten, dass es sich um eine Liste handelt (wie btk hervorhob):

list(reversed(range(10)))

Aktualisieren:

Wenn Sie nur rangedas gleiche Ergebnis erzielen möchten , können Sie alle Parameter verwenden.range(start, stop, step)

Um beispielsweise eine Liste zu erstellen [5,4,3,2,1,0], können Sie Folgendes verwenden:

range(5, -1, -1)

Es mag weniger intuitiv sein, aber wie in den Kommentaren erwähnt, ist dies effizienter und die richtige Verwendung des Bereichs für umgekehrte Listen.

Michał Šrajer
quelle
13
Obwohl es weniger effizient ist. Und Sie können keine Schneidevorgänge ausführen.
Jakob Bowyer
6
Diese Antwort ist sehr klar und leicht zu verstehen, muss es aber range(10)nicht sein range(9). Wenn Sie eine vollständig ausgearbeitete Liste (zum Schneiden usw.) wünschen, sollten Sie dies auch tun list(reversed(range(10))).
John Y
5
Dies erzeugt einen Iterator, OP fragt nach einem Ergebnis in Form einer Liste.
BTK
6
Die Verwendung von "umgekehrt" mit dem Python-Generator (vorausgesetzt, wir sprechen von der integrierten Python 3-Reihe) ist nur konzeptionell falsch und lehrt falsche Gewohnheiten, die Speicher- / Verarbeitungskomplexität beim Programmieren in Hochsprache nicht zu berücksichtigen.
Thedk
7
In Python3 werden reversedGeneratoren im Allgemeinen nicht akzeptiert, aber akzeptiert range. Warum sollte reversed(range(10000))Speicher für die gesamte Liste reserviert werden müssen? rangeKann ein Objekt zurückgegeben werden, das die __reversed__Methode implementiert, die eine effiziente umgekehrte Iteration ermöglicht?
Avmohan
312

Verwenden Sie die integrierte Funktion 'Bereich'. Die Unterschrift ist range(start, stop, step). Dies erzeugt eine Sequenz, die Zahlen ergibt, beginnend mit startund endend, wenn stoperreicht wurde, ausgenommen stop.

>>> range(9,-1,-1)   
    [9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
>>> range(-2, 6, 2)
    [-2, 0, 2, 4]

In Python 3 wird dadurch ein Nicht-Listen- rangeObjekt erzeugt, das effektiv wie eine schreibgeschützte Liste funktioniert (jedoch viel weniger Speicher benötigt, insbesondere für große Bereiche).

Herr B.
quelle
1
Kannst du das bitte auch erklären, kannst du mir bitte auch eine Website / ein PDF-Buch für Python
empfehlen
8
@ramesh Wenn Sie help(range)in einer Python-Shell ausgeführt werden, werden Ihnen die Argumente mitgeteilt . Sie sind die Nummer, mit der begonnen werden soll, die Nummer, mit der geendet werden soll (exklusiv) und der Schritt, der ausgeführt werden muss. Sie beginnt also bei 9 und subtrahiert 1, bis sie -1 erreicht (an diesem Punkt stoppt sie ohne Rückkehr, weshalb Der Bereich endet um 0)
Michael Mrozek
3
@ ramesh.mimit: Gehen Sie einfach auf die offizielle Python-Site. Dort finden Sie eine vollständige Dokumentation, einschließlich eines großartigen Tutorials.
John Y
5
Das ist wirklich die richtige Antwort, aber es könnte klarer erklärt werden. range(start, stop, step) - Beginnen Sie mit der Zahl startund erzielen Sie Ergebnisse, sofern stopdiese nicht erreicht wurden step.
Herr B
43

Sie könnten das verwenden, range(10)[::-1]was dasselbe ist range(9, -1, -1)und wahrscheinlich besser lesbar ist (wenn Sie mit der gängigen sequence[::-1]Python-Sprache vertraut sind ).

Martineau
quelle
28

Für diejenigen, die an der "Effizienz" der bisher gesammelten Optionen interessiert sind ...

Jaime RGP Antwort führte mich zu meinem Computer neu zu starten , nachdem Timing des etwas „herausfordernd“ Lösung von Jason buchstäblich nach meinem eigenen Vorschlag (via Kommentar). Um den Neugierigen die Ausfallzeiten zu ersparen, präsentiere ich hier meine Ergebnisse (Worst-First):

Jasons Antwort (vielleicht nur ein Ausflug in die Macht des Listenverständnisses ):

$ python -m timeit "[9-i for i in range(10)]"
1000000 loops, best of 3: 1.54 usec per loop

Martineaus Antwort (lesbar, wenn Sie mit der Syntax der erweiterten Slices vertraut sind ):

$ python -m timeit "range(10)[::-1]"
1000000 loops, best of 3: 0.743 usec per loop

Michał Šrajers Antwort (die akzeptierte, sehr lesbar):

$ python -m timeit "reversed(range(10))"
1000000 loops, best of 3: 0.538 usec per loop

bene Antwort (die erste, aber sehr lückenhaft zu dieser Zeit ):

$ python -m timeit "range(9,-1,-1)"
1000000 loops, best of 3: 0.401 usec per loop

Die letzte Option ist leicht zu merken, range(n-1,-1,-1)wenn man die Notation von Val Neekman verwendet .

Wolf
quelle
3
Ich habe meine eigenen Timings durchgeführt, bevor ich diese Antwort gelesen habe, und habe die gleichen Ergebnisse erzielt.
Todd Owen
13
for i in range(8, 0, -1)

wird dieses Problem lösen. Es wird 8 zu 1 ausgegeben und -1 bedeutet eine umgekehrte Liste

Jutta
quelle
10

Keine Verwendung, reverseda die Bereichsmethode eine umgekehrte Liste zurückgeben kann.

Wenn Sie eine Iteration über n Elemente haben und die von range(start, stop, step)Ihnen zurückgegebene Reihenfolge der Liste ersetzen möchten, müssen Sie den dritten Parameter des Bereichs verwenden, der ihn identifiziert stepund auf ihn -1setzt. Andere Parameter müssen entsprechend angepasst werden:

  1. Geben Sie Stop - Parameter wie -1(es vorherigen Wert ist stop - 1, stopwar gleich 0).
  2. Als Startparameter verwenden n-1.

Das Äquivalent des Bereichs (n) in umgekehrter Reihenfolge wäre also:

n = 10
print range(n-1,-1,-1) 
#[9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
Andriy Ivaneyko
quelle
6
Ehrlich gesagt finde ich das weniger intuitiv alsreversed(range(n))
Nicholas Hamilton
1
@NicholasHamilton Stimmen Sie zu, aber die Idee hinter dieser Antwort ist, weniger Ressourcen zu verwenden ... (und die Frage war über die Verwendung nur der Bereichsfunktion :))
Andriy Ivaneyko
Ok, keine Sorge, ich denke, es hängt von der Situation ab. Wenn beispielsweise die Bereichsfunktion als Index für eine Schleife verwendet wird, hat sie nur eine begrenzte Wirkung. Wenn sie jedoch innerhalb einer externen Schleife verwendet wird, erhöhen sich die Kosten ...
Nicholas Hamilton
8

Abgesehen von der Lesbarkeit reversed(range(n))scheint es schneller zu sein als 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

Nur wenn sich jemand wundert :)

Jaime RGP
quelle
gut, ein paar Zahlen zu haben :) - warum hast du nicht auch hinzugefügt range(1000000000-1,-1,-1)?
Wolf
... besser nicht timeit range(1000000000-1,-1,-1)in der Kommandozeile versuchen , sondern meine Ergebnisse sehen :-)
Wolf
6

Die Anforderung in dieser Frage erfordert eine listganze Zahl der Größe 10 in absteigender Reihenfolge. Lassen Sie uns also eine Liste in Python erstellen.

# 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
quelle
2
Ich mag das Triple-1 wirklich. Genau dieses Muster macht es einfach, es beizubehalten. wrap one's head around thisHeute habe ich gelernt, dass man es verwenden sollte , range(n-1, -1, -1)wenn man einen Bereich in umgekehrter Reihenfolge durchquert , wenn es wirklich effizient sein muss.
Wolf
5

Sie können umgekehrte Zahlen mit range () BIF Like, drucken.

for number in range ( 10 , 0 , -1 ) :
    print ( number ) 

Die Ausgabe wird [10,9,8,7,6,5,4,3,2,1] sein.

range () - Bereich (Start, Ende, Inkrement / Dekrement), wobei Start inklusive, Ende exklusiv ist und Inkrement beliebige Zahlen sein kann und sich wie ein Schritt verhält

Herr Suryaa Jha
quelle
5

Sehr oft gestellte Frage ist, ob range(9, -1, -1)besser als reversed(range(10))in Python 3? Personen, die mit Iteratoren in anderen Sprachen gearbeitet haben, neigen sofort dazu zu denken, dass reverse () alle Werte zwischenspeichern und dann in umgekehrter Reihenfolge zurückkehren muss. Der Python- reversed()Operator funktioniert nicht, wenn das Objekt nur ein Iterator ist. Das Objekt muss eine von unter zwei haben, damit reverse () funktioniert:

  1. Entweder Support- len()oder Integer-Indizes über[]
  2. Oder __reversed__()Methode implementiert haben.

Wenn Sie versuchen, reverse () für ein Objekt zu verwenden, das keines der oben genannten Elemente enthält, erhalten Sie:

>>> [reversed((x for x in range(10)))]
TypeError: 'generator' object is not reversible

Kurz gesagt, Pythons reversed()ist nur für Array-ähnliche Objekte gedacht und sollte daher die gleiche Leistung wie die Vorwärtsiteration haben.

Aber was ist mit range()? Ist das nicht ein Generator? In Python 3 ist es ein Generator, der jedoch in eine Klasse eingeschlossen ist, die beide oben genannten implementiert. Damitrange(100000) also nicht viel Speicher in Anspruch, unterstützt aber dennoch eine effiziente Indizierung und Umkehrung.

Zusammenfassend können Sie also reversed(range(10))ohne Leistungseinbußen verwenden.

Shital Shah
quelle
3

Ich glaube, das kann helfen,

range(5)[::-1]

unten ist Verwendung:

for i in range(5)[::-1]:
    print i 
Dineshsprabu
quelle
3
range(9,-1,-1)
[9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
Asinox
quelle
13
Ihre Antwort zeigt, warum reversed(range(10))weniger fehleranfällig ist. Nichts für ungut Asinox. Nur eine ehrliche Beobachtung.
Michał Šrajer
Ich weiß nicht, ob es Standard ist, falsche Antworten anzuzeigen. Kann ich oder jemand es korrigieren oder sogar entfernen?
Sinuskonata
3
@sine, nein, lass es einfach und frage dich, wie es 3 positive Stimmen gesammelt hat ... Ich nehme an, du könntest es für die Aufmerksamkeit des Moderators markieren (Duplikat der Antwort von 18 Monaten zuvor, außer gebrochen), nicht sicher, ob sie es löschen würden oder nicht.
OGHaza
Für alle zukünftigen Referenzen: Nur Code ist nicht VLQ , und falsche Antworten sollten auch nicht markiert werden . Downvote und mach weiter, aber das Markieren ist in diesem Fall falsch, egal ob NAA oder Mod-Flaggen. - Aus der Bewertung
Zoe
2

Verwenden ohne [:: - 1] oder umgekehrt -

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
quelle
6
Warum sollte jemand dies schreiben anstatt "python!"[::-1]?
Daniel
1
[9-i for i in range(10)]
[9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
Jason
quelle
1

Sie müssen nicht unbedingt die Bereichsfunktion verwenden, sondern können einfach die Liste [:: - 1] erstellen, die die Liste schnell in umgekehrter Reihenfolge zurückgeben soll, ohne Ergänzungen zu verwenden.

user7420740
quelle
Dies scheint die in einer früheren Antwort vorgeschlagene Lösung zu sein . Es scheint auch, dass Sie versuchen, eine andere vorherige Antwort zu kommentieren - Sie müssen ein bisschen mehr Ansehen erlangen, bevor Sie dies tun können.
Grisha Levit
1

Angenommen, Sie haben eine Liste mit dem Namen a = {1,2,3,4,5}. Wenn Sie die Liste nun in umgekehrter Reihenfolge drucken möchten, verwenden Sie einfach den folgenden Code.

a.reverse
for i in a:
   print(i)

Ich weiß, dass Sie mit Range gefragt haben, aber es ist bereits beantwortet.

Vishal Kumar
quelle
0
range(9,-1,-1)
    [9, 8, 7, 6, 5, 4, 3, 2, 1, 0]

Ist die richtige Form. Wenn du benutzt

reversed(range(10))

Sie erhalten keinen 0-Fall. Angenommen, Ihre 10 ist keine magische Zahl und eine Variable, mit der Sie nachschlagen, beginnt von hinten. Wenn Ihr n-Fall 0 ist, wird umgekehrt (Bereich (0)) nicht ausgeführt, was falsch ist, wenn Sie zufällig ein einzelnes Objekt im Nullindex haben.

user3807372
quelle
0

Ich dachte, dass viele (wie ich) mehr an einem häufigen Fall interessiert sein könnten, eine vorhandene Liste in umgekehrter Reihenfolge zu durchlaufen , wie im Titel angegeben, anstatt nur Indizes für eine solche Durchquerung zu generieren.

Auch wenn für diesen Fall immer noch die richtigen Antworten in Ordnung sind, möchte ich darauf hinweisen, dass der in Wolfs Antwort durchgeführte Leistungsvergleich nur zur Generierung von Indizes dient. Daher habe ich einen ähnlichen Benchmark für das Durchlaufen einer vorhandenen Liste in umgekehrter Reihenfolge erstellt.

TL; DR a[::-1] ist am schnellsten.

Voraussetzungen:

a = list(range(10))

Jasons Antwort :

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

Martineaus Antwort :

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

Antwort von Michał Šrajer :

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

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

Wie Sie sehen, müssen in diesem Fall keine Indizes explizit generiert werden. Die schnellste Methode ist also die, die weniger zusätzliche Aktionen ausführt.

NB: Ich habe in JupyterLab getestet, das einen praktischen "magischen Befehl" hat %timeit. Es verwendet Standard timeit.timeitunter der Haube. Getestet für Python 3.7.3

pkuderov
quelle