una renombrar recorrer nombre eliminar data columnas columna cambiar borrar python list performance replace

renombrar - Reemplazar valores en la lista usando Python



recorrer data frame pandas (7)

Tengo una lista en la que deseo reemplazar los valores por None donde condition () devuelve True.

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

Por ejemplo, si la condición comprueba bool (elemento% 2) debería devolver:

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

¿Cuál es la forma más eficiente de hacer esto?


Aquí hay otra forma:

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


Crea una nueva lista con una lista de comprensión:

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

Puede modificar la lista original in situ si lo desea, pero en realidad no ahorra tiempo:

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

Aquí están los tiempos de (Python 3.6.3) que demuestran el timeave:

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)

Y tiempos de Python 2.7.6:

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


En caso de que desee reemplazar los valores en su lugar, puede actualizar su lista original con los valores de una lista de comprensión mediante la asignación de la porción entera del original.

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

Si tiene varios nombres que apuntan a la lista original, por ejemplo, usted escribió data2=data antes de cambiar la lista y omite la notación de división para asignar data , los data volverán a enlazar para apuntar a la lista recién creada mientras data2 aún apunta al original lista sin cambios.

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]

Nota: Esto no es una recomendación para generalmente preferir uno sobre el otro (cambiar la lista en su lugar o no), sino un comportamiento que debe tener en cuenta.


Esto podría ayudar ...

test_list = [5, 8] test_list[0] = None print test_list #prints [None, 8]


Riffing en una pregunta lateral formulada por el OP en un comentario, es decir:

¿Y si tuviera un generador que arroje los valores del rango (11) en lugar de una lista? ¿Sería posible reemplazar valores en el generador?

Claro, es trivialmente fácil ...

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

Simplemente pase cualquier iterable (incluido el resultado de llamar a un generador) como la primera arg, el predicado para decidir si un valor debe ser reemplazado como la segunda arg, y deje que se rompa.

Por ejemplo:

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


>>> 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]


ls = [x if (condition) else None for x in ls]