Crear una lista de un solo elemento repetido N veces

Resuelto chimeracoder asked hace 14 años • 10 respuestas

Quiero crear una serie de listas, todas de diferentes longitudes. Cada lista contendrá el mismo elemento e, repetido nveces (donde n= longitud de la lista).

¿Cómo creo las listas sin utilizar una lista de comprensión [e for number in xrange(n)]para cada lista?

chimeracoder avatar Aug 11 '10 21:08 chimeracoder
Aceptado

También puedes escribir:

[e] * n

Debe tener en cuenta que si e es, por ejemplo, una lista vacía, obtendrá una lista con n referencias a la misma lista, no n listas vacías independientes.

Pruebas de rendimiento

A primera vista parece que repetir es la forma más rápida de crear una lista con n elementos idénticos:

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

Pero espera, no es una prueba justa...

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

¡ La función itertools.repeaten realidad no crea la lista, simplemente crea un objeto que puede usarse para crear una lista si lo desea! Intentemos eso nuevamente, pero convirtiéndolo a una lista:

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

Entonces, si quieres una lista, usa [e] * n. Si desea generar los elementos de forma perezosa, utilice repeat.

Mark Byers avatar Aug 11 '2010 14:08 Mark Byers
>>> [5] * 4
[5, 5, 5, 5]

Tenga cuidado cuando el elemento que se repite es una lista. La lista no será clonada: ¡todos los elementos harán referencia a la misma lista!

>>> x=[5]
>>> y=[x] * 4
>>> y
[[5], [5], [5], [5]]
>>> y[0][0] = 6
>>> y
[[6], [6], [6], [6]]
minou avatar Aug 11 '2010 14:08 minou

Crear una lista de un solo elemento repetido n veces en Python

Dependiendo de su caso de uso, querrá utilizar diferentes técnicas con diferente semántica.

Multiplica una lista de elementos inmutables

Para elementos inmutables, como Ninguno, bools, ints, floats, strings, tuplas o frozensets, puedes hacerlo así:

[e] * 4

Por ejemplo:

>>> [None] * 4
[None, None, None, None]

Tenga en cuenta que esto generalmente solo se usa con elementos inmutables (cadenas, tuplas, conjuntos congelados, etc.) en la lista, porque todos apuntan al mismo elemento en el mismo lugar en la memoria.

Como ejemplo de caso de uso, uso esto cuando tengo que crear una tabla con un esquema de todas las cadenas, para no tener que realizar una asignación uno a uno altamente redundante.

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

Multiplica la lista donde queremos que se repita el mismo elemento con estado mutable

Multiplicar una lista nos da los mismos elementos una y otra vez. La necesidad de esto es poco frecuente:

[iter(iterable)] * 4

A veces esto se utiliza para asignar un iterable a una lista de listas:

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

Podemos ver que a_listcontiene el mismo iterador de rango cuatro veces:

>>> from pprint import pprint
>>> pprint(a_list)
[<range_iterator object at 0x7f9fe3b58420>,
 <range_iterator object at 0x7f9fe3b58420>,
 <range_iterator object at 0x7f9fe3b58420>,
 <range_iterator object at 0x7f9fe3b58420>]

elementos mutables

He usado Python durante mucho tiempo y he visto muy pocos casos de uso en los que haría lo anterior con objetos mutables.

En lugar de eso, para repetir, digamos, una lista, un conjunto o un dictado mutable y vacío, deberías hacer algo como esto:

list_of_lists = [[] for _ in iterator_of_needed_length]

El guión bajo es simplemente un nombre de variable descartable en este contexto.

Si solo tienes el número, ese sería:

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

El _nombre desechable no es realmente especial, pero un analizador de código estático probablemente se quejará si no tiene intención de utilizar la variable y utilizar cualquier otro nombre.


Advertencias sobre el uso del método de multiplicación con elementos mutables:

Tenga cuidado al hacer esto con objetos mutables , cuando cambia uno de ellos, todos cambian porque todos son el mismo objeto:

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

foo ahora regresa:

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

Pero con objetos inmutables, puedes hacer que funcione porque cambias la referencia, no el objeto:

>>> 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([])]

Pero nuevamente, los objetos mutables no sirven para esto, porque las operaciones in situ cambian el objeto, no la referencia:

l = [set()] * 4
>>> l[0] |= set('abc')    
>>> l
[set(['a', 'c', 'b']), set(['a', 'c', 'b']), set(['a', 'c', 'b']), set(['a', 'c', 'b'])]
Russia Must Remove Putin avatar Jul 03 '2014 15:07 Russia Must Remove Putin