812 Stimmen

Erstellen einer Liste mit einem einzelnen Element, das N-mal wiederholt wird

Ich möchte eine Reihe von Listen erstellen, die alle unterschiedlich lang sind. Jede Liste wird das gleiche Element enthalten e , wiederholt n mal (wobei n = Länge der Liste).

Wie erstelle ich die Listen, ohne ein Listenverständnis zu verwenden? [e for number in xrange(n)] für jede Liste?

1187voto

Mark Byers Punkte 761508

Sie können auch schreiben:

[e] * n

Wenn e zum Beispiel eine leere Liste ist, erhält man eine Liste mit n Verweisen auf dieselbe Liste, nicht n unabhängige leere Listen.

Leistungsprüfung

Auf den ersten Blick scheint dass die Wiederholung der schnellste Weg ist, 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 halt - das ist kein fairer Test...

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

Die Funktion itertools.repeat erstellt nicht wirklich eine Liste, sondern nur ein Objekt, das zur Erstellung einer Liste verwendet werden kann, wenn Sie dies wünschen! Versuchen wir das noch einmal, aber mit der Umwandlung in eine Liste:

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

Wenn Sie also eine Liste wollen, verwenden Sie [e] * n . Wenn Sie die Elemente träge generieren wollen, verwenden Sie repeat .

226voto

gaefan Punkte 15124
>>> [5] * 4
[5, 5, 5, 5]

Seien Sie vorsichtig, wenn das zu wiederholende Element eine Liste ist. Die Liste wird nicht geklont: alle Elemente beziehen sich auf die gleiche Liste!

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

132voto

Erstellen einer Liste mit einem einzelnen Element, das n-mal wiederholt wird, in Python

Je nach Anwendungsfall sollten Sie verschiedene Techniken mit unterschiedlicher Semantik verwenden.

Multiplizieren einer Liste für unveränderliche Elemente

Für unveränderliche Elemente, wie None, bools, ints, floats, strings, tuples oder frozensets, können Sie es so machen:

[e] * 4

Beachten Sie, dass dies in der Regel nur bei unveränderlichen Elementen (Strings, Tupel, Frozensets, ) in der Liste verwendet wird, da sie alle auf das gleiche Element an der gleichen Stelle im Speicher verweisen. Ich verwende dies häufig, wenn ich eine Tabelle mit einem Schema aller Strings erstellen muss, damit ich keine hochgradig redundante Eins-zu-Eins-Zuordnung vornehmen muss.

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

Multiplizieren Sie die Liste, in der derselbe Eintrag wiederholt werden soll

Die Multiplikation einer Liste ergibt die dieselbe Elemente wieder und wieder. Dies ist nur selten erforderlich:

[iter(iterable)] * 4

Dies wird manchmal verwendet, um eine iterable in eine Liste von Listen abzubilden:

>>> iterable = range(12)
>>> a_list = [iter(iterable)] * 4
>>> [[next(l) for l in a_list] for i in range(3)]
[[0, 1, 2, 3], [4, 5, 6, 7], [8, 9, 10, 11]]

Wir können sehen, dass a_list enthält viermal denselben Bereichs-Iterator:

>>> a_list
[<range_iterator object at 0x7fde73a5da20>, <range_iterator object at 0x7fde73a5da20>, <range_iterator object at 0x7fde73a5da20>, <range_iterator object at 0x7fde73a5da20>]

Veränderliche Gegenstände

Ich habe Python für eine lange Zeit jetzt verwendet, und ich habe sehr wenige Anwendungsfälle gesehen, wo ich die oben mit veränderlichen Objekten tun würde.

Stattdessen, um, sagen wir, eine veränderbare leere Liste, Menge oder Dikt zu erhalten, sollten Sie etwas wie folgt tun:

list_of_lists = [[] for _ in columns]

Der Unterstrich ist in diesem Zusammenhang einfach ein Wegwerfvariablenname.

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

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

Le site _ ist eigentlich nichts Besonderes, aber die Stilprüfung Ihrer Programmierumgebung wird sich wahrscheinlich beschweren, wenn Sie die Variable nicht verwenden wollen und einen anderen Namen verwenden.


Vorbehalte bei der Verwendung der unveränderlichen Methode mit veränderlichen Elementen:

Vorsicht bei der Verwendung von veränderlichen Objekten Wenn man einen von ihnen ändert, ändern sich alle, weil sie alle gleich sind. dieselbe Objekt:

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

foo kehrt nun zurück:

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

Aber mit unveränderlichen Objekten kann man es schaffen, weil man die Referenz ändert, 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änderbare Objekte nicht geeignet, da die Operationen an Ort und Stelle das Objekt und nicht die Referenz ändern:

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

32voto

Jochen Ritzel Punkte 99416

Itertools verfügt über eine Funktion für diesen Zweck:

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

Natürlich itertools gibt Ihnen einen Iterator anstelle einer Liste. [e] * n gibt Ihnen eine Liste, aber je nachdem, was Sie mit diesen Sequenzen machen wollen, muss die itertools Variante viel effizienter sein kann.

18voto

W.P. McNeill Punkte 14851

Wie bereits von anderen erwähnt, werden durch die Verwendung des *-Operators für ein veränderbares Objekt Verweise dupliziert, so dass sich bei einer Änderung alle Verweise ändern. Wenn Sie unabhängige Instanzen eines veränderlichen Objekts erstellen wollen, ist Ihre xrange-Syntax die pythonischste Art, dies zu tun. Wenn es Sie stört, eine benannte Variable zu haben, die nie verwendet wird, können Sie die anonyme Unterstrichvariable verwenden.

[e for _ in xrange(n)]

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X