Der kürzeste Weg, um gerade / ungerade Zeilen aus einem Python-Array herauszuschneiden?

77

Oder eine allgemeinere Frage wäre, wie man ein Array schneidet, um jede n-te Zeile zu erhalten. Für gerade / ungerade möchten Sie also eine Zeile überspringen, aber im allgemeinen Fall möchten Sie jede n-te Zeile erhalten th Zeilen, n-1 Zeilen überspringen.

fette Katze
quelle
1
Ich weiß, dass ich es in einer Schleife damit machen kann, aber ich habe mich gefragt, ob ich es stattdessen nur in einer Zeile machen kann
Fatcat
Gute Frage. Die Antworten hier haben mir auch geholfen. Großartig, Merci.
Siyah

Antworten:

164

Angenommen, Sie sprechen von einer Liste , geben Sie den Schritt im Slice an (und starten den Index). Die Syntax lautet list[start:end:step].

Sie kennen wahrscheinlich den normalen Listenzugriff, um einen Artikel zu erhalten, z. B. l[2]um den dritten Artikel zu erhalten. Wenn Sie zwei Zahlen und einen Doppelpunkt dazwischen angeben, können Sie einen Bereich angeben , den Sie aus der Liste abrufen möchten. Der Rückgabewert ist eine andere Liste. ZB l[2:5]gibt Ihnen den dritten bis sechsten Punkt. Sie können auch eine optionale dritte Nummer übergeben, die die Schrittgröße angibt. Die Standardschrittgröße ist eins, dh nur jedes Element (zwischen Start- und Endindex).

Beispiel:

>>> l = range(10)
>>> l[::2]         # even  - start at the beginning at take every second item
[0, 2, 4, 6, 8]
>>> l[1::2]        # odd - start at second item and take every second item
[1, 3, 5, 7, 9]

Siehe Listen im Python-Tutorial .

Wenn Sie jedes n-te Element einer Liste erhalten möchten (dh das erste Element ausschließen), müssten Sie wie schneiden l[(n-1)::n].

Beispiel:

>>> l = range(20)
>>> l
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]

Jetzt wäre jedes dritte Element:

>>> l[2::3]
[2, 5, 8, 11, 14, 17]

Wenn Sie das erste Element einfügen möchten, tun Sie dies einfach l[::n].

Felix Kling
quelle
Das habe ich noch nie gesehen. Die erste Zahl ist der Anfangsindex und die letzte ist dann der Schritt? Geht irgendetwas zwischen den ::? Oder sind beide ein Operator, der sich von unterscheidet :? Wenn ich dann l[::1]das Original-Array bekomme?
Fatcat
1
@fatcat - docs.python.org/library/… , siehe Anmerkungen 3 & 5
Jeremy Brown
@fatcat: Ja, Sie würden das ursprüngliche Array erhalten. Ich würde sagen, öfter sehen Sie nur einen Ausschnitt von einem Start- zu einem Endindex, wie z l[2:5]. Der Schritt ist optional.
Felix Kling
1

Dies ist mehr für mich als vollständiges Beispiel;)

>>> import itertools
>>> ret = [[1,2], [3,4,5,6], [7], [8,9]]
>>> itertools.izip_longest(*ret)
>>> [x for x in itertools.chain.from_iterable(tmp) if x is not None]
[1, 3, 7, 8, 2, 4, 9, 5, 6]
delijati
quelle
-1
> map(lambda index: arr[index],filter(lambda x: x%n == 0,range(len(arr))))

Wo arrist eine Liste, und nSlices sind erforderlich.

Ajmartin
quelle
1
-1 für die Verwendung map()und filter()mit a lambda. Dies ist nicht empfehlenswert / langsam und sollte immer mit einem Listenverständnis erfolgen.
ThiefMaster
1
Gibt es Experimente, die diese Behauptung stützen?
Ajmartin
1
Ich denke, es gibt irgendwo im Archiv der Python-Mailingliste einen Beitrag von Guido van Rossum darüber. Wie auch immer, es ist ziemlich offensichtlich, da es sich um einen Funktionsaufruf oder keinen Funktionsaufruf handelt. Es sei denn, Sie verwenden
stapellose Anruffunktionen