Frage

Ich weiß, dass ein Listenverständnis dies tun wird, aber ich habe mich gefragt, ob es einen noch kürzeren (und mehr pythonischen?) Ansatz gibt.

Ich möchte eine Reihe von Listen erstellen, die alle unterschiedliche Länge haben. Jede Liste enthält das gleiche Element E, wiederholt n -mal (wobei n = Länge der Liste). Wie erstelle ich die Listen, ohne zu tun?

[e for number in xrange(n)]

Für jede Liste?

War es hilfreich?

Lösung

Sie können auch schreiben:

[e] * n

Sie sollten beachten, dass Sie, wenn E beispielsweise eine leere Liste ist, eine Liste mit n Referenzen auf dieselbe Liste erhalten, nicht auf n unabhängige leere Listen.

Leistungstest

Auf den ersten Blick es scheint Diese Wiederholung ist der schnellste Weg, um eine Liste mit n identischen Elementen zu erstellen:

>>> timeit.timeit('itertools.repeat(0, 10)', 'import itertools', number = 1000000)
0.37095273281943264
>>> timeit.timeit('[0] * 10', 'import itertools', number = 1000000)
0.5577236771712819

Aber warte - es ist kein fairer Test ...

>>> itertools.repeat(0, 10)
repeat(0, 10)  # Not a list!!!

Die Funktion itertools.repeat Erstellt die Liste nicht, sondern erstellt nur ein Objekt, mit dem eine Liste erstellt werden kann, wenn Sie möchten! Versuchen wir das noch einmal, aber konvertieren wir sie in eine Liste:

>>> timeit.timeit('list(itertools.repeat(0, 10))', 'import itertools', number = 1000000)
1.7508119747063233

Wenn Sie also eine Liste möchten, verwenden Sie [e] * n. Wenn Sie die Elemente faul generieren möchten, verwenden Sie repeat.

Andere Tipps

>>> [5] * 4
[5, 5, 5, 5]

Seien Sie vorsichtig, wenn das wiederholte Element eine Liste ist. Die Liste wird nicht geklont: Alle Elemente beziehen sich auf dieselbe Liste!

>>> x=[5]
>>> y=[x] * 4
>>> y
[[5], [5], [5], [5]]
>>> y[0][0] = 6
>>> y
[[6], [6], [6], [6]]

Erstellen Sie die Liste der einzelnen Elemente, die n -mal in Python wiederholt wurden

Unveränderliche Gegenstände

Für unveränderliche Gegenstände, wie keine, Saiten, Tupel oder Frodensets, können Sie es so tun:

[e] * 4

Beachten Sie, dass dies am besten nur mit unveränderlichen Elementen (Zeichenfolgen, Tupeln, Gefrierungen) in der Liste verwendet wird, da sie alle auf dasselbe Element an derselben Stelle im Speicher hinweisen. Ich benutze dies häufig, wenn ich einen Tisch mit einem Schema aller Saiten erstellen muss, damit ich keine eins -zu -Eins -Kartierung geben muss.

schema = ['string'] * len(columns)

Veränderliche Gegenstände

Ich habe Python schon lange verwendet und habe noch nie einen Anwendungsfall gesehen, in dem ich das oben oben mit einer veränderlichen Instanz machen würde. Um beispielsweise eine veränderliche leere Liste, festzulegen oder zu dikten, sollten Sie so etwas tun:

list_of_lists = [[] for _ in columns]

Der Unterstrich ist in diesem Zusammenhang einfach ein wegwerfender variabler Name.

Wenn Sie nur die Nummer haben, wäre das:

list_of_lists = [[] for _ in range(4)]

Das _ ist nicht wirklich etwas Besonderes, aber Ihr Codierungsumgebungsstil -Checker wird sich wahrscheinlich beschweren, wenn Sie die Variable nicht verwenden und einen anderen Namen verwenden.


Vorbehalte für die unveränderliche Methode mit veränderlichen Elementen:

Achten Sie darauf, dass Sie dies mit veränderlichen Objekten tun, Wenn Sie einen von ihnen ändern, ändern sie sich alle, weil sie alle sind gleich Objekt:

foo = [[]] *4
foo[0].append('x')

Foo kehrt jetzt zurück:

[['x'], ['x'], ['x'], ['x']]

Mit unveränderlichen Objekten können Sie es jedoch zum Laufen bringen, weil Sie die Referenz ändern, nicht das Objekt:

>>> l = [0] * 4
>>> l[0] += 1
>>> l
[1, 0, 0, 0]

>>> l = [frozenset()] * 4
>>> l[0] |= set('abc')
>>> l
[frozenset(['a', 'c', 'b']), frozenset([]), frozenset([]), frozenset([])]

Aber auch hier sind veränderliche Objekte dafür nicht gut, da In-Place-Operationen das Objekt ändern, nicht die Referenz:

l = [set()] * 4
>>> l[0] |= set('abc')    
>>> l
[set(['a', 'c', 'b']), set(['a', 'c', 'b']), set(['a', 'c', 'b']), set(['a', 'c', 'b'])]

Itrertools hat eine Funktion dafür:

import itertools
it = itertools.repeat(e,n)

Na sicher itertools Gibt Ihnen einen Iterator anstelle einer Liste. [e] * n gibt Ihnen eine Liste, aber je nachdem, was Sie mit diesen Sequenzen tun werden, die itertools Variante kann viel effizienter sein.

Wie andere betont haben, dupliziert die Verwendung des * Operators für ein veränderliches Objekt Referenzen. Wenn Sie also eines ändern, ändern Sie sie alle. Wenn Sie unabhängige Instanzen eines veränderlichen Objekts erstellen möchten, ist Ihre Xrange -Syntax die pythonischste Art, dies zu tun. Wenn Sie sich durch eine benannte Variable stören, die nie verwendet wird, können Sie die anonyme Unterstrichvariable verwenden.

[e for _ in xrange(n)]
[e] * n

sollte arbeiten

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top