it-swarm.com.de

Ersetzen Sie die Werte in der Liste mit Python

Ich habe eine Liste, in der ich Werte durch Keine ersetzen möchte, wobei condition () True zurückgibt.

[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

Wenn Bedingungsprüfungen bool (Element% 2) beispielsweise zurückgegeben werden sollen:

[None, 1, None, 3, None, 5, None, 7, None, 9, None]

Was ist der effizienteste Weg, dies zu tun?

108
ak.

Erstellen Sie eine neue Liste mit einem Listenverständnis:

new_items = [x if x % 2 else None for x in items]

Sie können die ursprüngliche Liste vor Ort ändern, wenn Sie möchten, es spart jedoch keine Zeit:

items = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
for index, item in enumerate(items):
    if not (item % 2):
        items[index] = None

Hier sind (Python 3.6.3) Timings, die die Nicht-Zeitspeicherung demonstrieren:

In [1]: %%timeit
   ...: items = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
   ...: for index, item in enumerate(items):
   ...:     if not (item % 2):
   ...:         items[index] = None
   ...:
1.06 µs ± 33.7 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)

In [2]: %%timeit
   ...: items = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
   ...: new_items = [x if x % 2 else None for x in items]
   ...:
891 ns ± 13.6 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)

Und Python 2.7.6-Timings:

In [1]: %%timeit
   ...: items = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
   ...: for index, item in enumerate(items):
   ...:     if not (item % 2):
   ...:         items[index] = None
   ...: 
1000000 loops, best of 3: 1.27 µs per loop
In [2]: %%timeit
   ...: items = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
   ...: new_items = [x if x % 2 else None for x in items]
   ...: 
1000000 loops, best of 3: 1.14 µs per loop
156
John Millikin
ls = [x if (condition) else None for x in ls]
61

Riffing auf eine vom OP in einem Kommentar gestellte Nebenfrage, d. H .:

was wäre, wenn ich einen Generator hätte, der ergibt die Werte aus Bereich (11) anstelle von Liste. Wäre es möglich, .__ zu ersetzen. Werte im Generator?

Sicher, es ist trivial einfach ...:

def replaceiniter(it, predicate, replacement=None):
  for item in it:
    if predicate(item): yield replacement
    else: yield item

Übergeben Sie einfach jedes iterierbare Element (einschließlich des Ergebnisses des Aufrufs eines Generators) als erstes Argument, das Prädikat, um zu entscheiden, ob ein Wert als zweites Argument ersetzt werden muss, und lassen Sie ihn rippen.

Zum Beispiel:

>>> list(replaceiniter(xrange(11), lambda x: x%2))
[0, None, 2, None, 4, None, 6, None, 8, None, 10]
10
Alex Martelli

Hier ist ein anderer Weg:

>>> L = range (11)
>>> map(lambda x: x if x%2 else None, L)
[None, 1, None, 3, None, 5, None, 7, None, 9, None]
9
balpha
>>> L = range (11)
>>> [ x if x%2 == 1 else None for x in L ]
[None, 1, None, 3, None, 5, None, 7, None, 9, None]
2
eduffy

Wenn Sie vorhandene Werte ersetzen möchten, können Sie Ihre ursprüngliche Liste durch Werte aus einem Listenverständnis aktualisieren, indem Sie dem gesamten Teil des Originals zuweisen.

data = [*range(11)] # [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
id_before = id(data)
data[:] = [x if x % 2 else None for x in data]
data
# Out: [None, 1, None, 3, None, 5, None, 7, None, 9, None]
id_before == id(data)  # check if list is still the same
# Out: True

Wenn Sie mehrere Namen haben, die auf die ursprüngliche Liste verweisen, haben Sie beispielsweise data2=data bevor Sie die Liste ändern und die Slice-Notation für die Zuweisung zu data überspringen, wird data erneut gebunden, um auf die neu erstellte Liste zu zeigen, während data2 zeigt immer noch auf die ursprüngliche unveränderte Liste.

data = [*range(11)] # [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
data2 = data
id_before = id(data)
data = [x if x % 2 else None for x in data]  # no [:] here
data
# Out: [None, 1, None, 3, None, 5, None, 7, None, 9, None]
id_before == id(data)  # check if list is still the same
# Out: False
data2
# Out: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

Hinweis: Dies ist keine Empfehlung für den generellen Vorzug vor der anderen (Änderung der Liste oder nicht), aber Verhalten, das Sie kennen sollten.

0
Darkonaut