Ich brauche die letzten 9 Nummern einer Liste und ich bin mir sicher, dass es eine Möglichkeit gibt, dies mit dem Schneiden zu tun, aber ich kann es scheinbar nicht verstehen. Ich kann die ersten 9 so bekommen:
num_list[0:9]
Ich brauche die letzten 9 Nummern einer Liste und ich bin mir sicher, dass es eine Möglichkeit gibt, dies mit dem Schneiden zu tun, aber ich kann es scheinbar nicht verstehen. Ich kann die ersten 9 so bekommen:
num_list[0:9]
Antworten:
Sie können dafür negative Ganzzahlen mit dem Slicing-Operator verwenden. Hier ist ein Beispiel mit dem Python-CLI-Interpreter:
>>> a = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
>>> a
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
>>> a[-9:]
[4, 5, 6, 7, 8, 9, 10, 11, 12]
Die wichtige Linie ist a[-9:]
-0
ist 0
. So a[-0:]
kehrt ganze a
, nicht die letzten Null - Elemente []
. Zum Schutz von Null können Sie verwenden a[-n:] if n > 0 else []
.
Python-Slicing ist eine unglaublich schnelle Operation und eine praktische Möglichkeit, schnell auf Teile Ihrer Daten zuzugreifen.
Die Slice-Notation zum Abrufen der letzten neun Elemente aus einer Liste (oder einer anderen Sequenz, die dies unterstützt, z. B. eine Zeichenfolge) sieht folgendermaßen aus:
num_list[-9:]
Wenn ich das sehe, lese ich den Teil in den Klammern als "9. vom Ende bis zum Ende". (Eigentlich verkürze ich es mental als "-9, on")
Die vollständige Notation ist
sequence[start:stop:step]
Aber der Doppelpunkt sagt Python, dass Sie ihm ein Slice und keinen regulären Index geben. Deshalb ist die idiomatische Art, Listen in Python 2 zu kopieren, die folgende
list_copy = sequence[:]
Und sie zu löschen ist mit:
del my_list[:]
(Listen erhalten list.copy
und list.clear
in Python 3.)
Es kann nützlich sein, die Bildung des Slice von der Übergabe an die list.__getitem__
Methode zu trennen ( genau das tun die eckigen Klammern ). Selbst wenn Sie nicht neu darin sind, bleibt Ihr Code besser lesbar, sodass andere, die Ihren Code möglicherweise lesen müssen, besser verstehen können, was Sie tun.
Sie können einer Variablen jedoch nicht einfach einige durch Doppelpunkte getrennte Ganzzahlen zuweisen. Sie müssen das Slice-Objekt verwenden:
last_nine_slice = slice(-9, None)
Das zweite Argument None
ist erforderlich, damit das erste Argument als start
Argument interpretiert wird, andernfalls wäre es das stop
Argument .
Sie können das Slice-Objekt dann an Ihre Sequenz übergeben:
>>> list(range(100))[last_nine_slice]
[91, 92, 93, 94, 95, 96, 97, 98, 99]
islice
islice
aus dem itertools-Modul ist ein weiterer möglicherweise performanter Weg, um dies zu erhalten. islice
nimmt keine negativen Argumente an, daher hat Ihre iterable im Idealfall eine __reversed__
spezielle Methode - welche Liste hat - also müssen Sie zuerst Ihre Liste (oder iterable with __reversed__
) an übergeben reversed
.
>>> from itertools import islice
>>> islice(reversed(range(100)), 0, 9)
<itertools.islice object at 0xffeb87fc>
islice ermöglicht eine verzögerte Auswertung der Datenpipeline. Um die Daten zu materialisieren, übergeben Sie sie an einen Konstruktor (wie list
):
>>> list(islice(reversed(range(100)), 0, 9))
[99, 98, 97, 96, 95, 94, 93, 92, 91]
Die letzten 9 Elemente können mit numlist [-9:] von links nach rechts oder mit numlist [: - 10: -1] von rechts nach links gelesen werden.
>>> a=range(17)
>>> print a
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]
>>> print a[-9:]
[8, 9, 10, 11, 12, 13, 14, 15, 16]
>>> print a[:-10:-1]
[16, 15, 14, 13, 12, 11, 10, 9, 8]
Hier sind verschiedene Optionen, um die "Schwanz" -Elemente einer Iterable zu erhalten:
Gegeben
n = 9
iterable = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
Gewünschte Ausgabe
[2, 3, 4, 5, 6, 7, 8, 9, 10]
Code
Wir erhalten die letztere Ausgabe mit einer der folgenden Optionen:
from collections import deque
import itertools
import more_itertools
# A: Slicing
iterable[-n:]
# B: Implement an itertools recipe
def tail(n, iterable):
"""Return an iterator over the last *n* items of *iterable*.
>>> t = tail(3, 'ABCDEFG')
>>> list(t)
['E', 'F', 'G']
"""
return iter(deque(iterable, maxlen=n))
list(tail(n, iterable))
# C: Use an implemented recipe, via more_itertools
list(more_itertools.tail(n, iterable))
# D: islice, via itertools
list(itertools.islice(iterable, len(iterable)-n, None))
# E: Negative islice, via more_itertools
list(more_itertools.islice_extended(iterable, -n, None))
Einzelheiten
iter(iterable)
.itertools
Rezept . Es ist verallgemeinert, um an jedem iterierbaren Element zu arbeiten, und behebt das Iteratorproblem in der letzten Lösung. Dieses Rezept muss manuell implementiert werden, da es nicht offiziell in der enthalten istitertools
Modul enthalten ist.more_itertools
(install via > pip install more-itertools
); siehe more_itertools.tail
.itertools
Bibliothek. Beachten Sie, itertools.islice
dass negatives Schneiden nicht unterstützt wird . more_itertools
, das verallgemeinert itertools.islice
, um das negative Schneiden zu unterstützen. siehe more_itertools.islice_extended
.Welches benutze ich?
Es kommt darauf an . In den meisten Fällen ist das Schneiden (Option A, wie in anderen Antworten erwähnt) die einfachste Option, da es in die Sprache integriert ist und die meisten iterierbaren Typen unterstützt. Verwenden Sie für allgemeinere Iteratoren eine der verbleibenden Optionen. Hinweis: Für die Optionen C und E muss eine Bibliothek eines Drittanbieters installiert werden, die einige Benutzer möglicherweise nützlich finden.