Crea una lista vacía en python con cierto tamaño


546

Quiero crear una lista vacía (o lo que sea la mejor manera) que puede contener 10 elementos.

Después de eso, quiero asignar valores en esa lista, por ejemplo, se supone que esto muestra de 0 a 9:

s1 = list();
for i in range(0,9):
   s1[i] = i

print  s1

Pero cuando ejecuto este código, genera un error o, en otro caso, solo se muestra [](vacío).

¿Alguien puede explicar por qué?



77
Una "lista vacía" ( []) por definición tiene cero elementos. Lo que aparentemente quiere es una lista de valores Falsy como None, 0, o ''.
dan04

Para generar una lista de 0a 9debería usar for i in range(0, 10), lo que significa for (int i = 0, i < 10, i++).
Atcold

Respuestas:


833

No puede asignar a una lista como lst[i] = something, a menos que la lista ya esté inicializada con al menos i+1elementos. Debe usar append para agregar elementos al final de la lista. lst.append(something).

(Podría usar la notación de asignación si estuviera usando un diccionario).

Crear una lista vacía:

>>> l = [None] * 10
>>> l
[None, None, None, None, None, None, None, None, None, None]

Asignación de un valor a un elemento existente de la lista anterior:

>>> l[1] = 5
>>> l
[None, 5, None, None, None, None, None, None, None, None]

Tenga en cuenta que algo así l[15] = 5todavía fallaría, ya que nuestra lista tiene solo 10 elementos.

range (x) crea una lista de [0, 1, 2, ... x-1]

# 2.X only. Use list(range(10)) in 3.X.
>>> l = range(10)
>>> l
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

Usando una función para crear una lista:

>>> def display():
...     s1 = []
...     for i in range(9): # This is just to tell you how to create a list.
...         s1.append(i)
...     return s1
... 
>>> print display()
[0, 1, 2, 3, 4, 5, 6, 7, 8]

Comprensión de la lista (Usando los cuadrados porque para el rango no necesita hacer todo esto, puede regresar range(0,9)):

>>> def display():
...     return [x**2 for x in range(9)]
... 
>>> print display()
[0, 1, 4, 9, 16, 25, 36, 49, 64]

17
¿Qué quiere decir con "No puede asignar a una lista como lst [i] = algo" - por supuesto que puede! Lo que no puede hacer es asignar a un elemento inexistente más allá de la longitud de la lista actual
Sergey

55
"a menos que la lista ya esté inicializada con al menos i + 1 elementos" ....
MrR

55
puedes hacer esto:a = [0 for _ in range(10)]
Kamiar

¿Es posible hacer esto usando la función list ()?
Raúl Chiarella

126

Intenta esto en su lugar:

lst = [None] * 10

Lo anterior creará una lista de tamaño 10, donde se inicializa cada posición None. Después de eso, puede agregarle elementos:

lst = [None] * 10
for i in range(10):
    lst[i] = i

Es cierto que esa no es la forma pitónica de hacer las cosas. Mejor haz esto:

lst = []
for i in range(10):
    lst.append(i)

O incluso más simple , en Python 2.x puede hacer esto para inicializar una lista con valores de 0 a 9:

lst = range(10)

Y en Python 3.x:

lst = list(range(10))

2
La otra gran cosa acerca de esto es que puede inicializar una lista con valores predeterminados. lst = [''] * 10olst = [0] * 10
Anthony Manning-Franklin el

2
Una variante en el ejemplo de comprensión. Si todos los elementos de la necesidad matriz que se vacía en la inicialización, utilice: arr = [None for _ in range(10)].
Doug R.

86

respuesta aceptada actualmente de varunl

 >>> l = [None] * 10
 >>> l
 [None, None, None, None, None, None, None, None, None, None]

Funciona bien para tipos sin referencia como los números. Lamentablemente, si desea crear una lista de listas, se encontrará con errores de referencia. Ejemplo en Python 2.7.6:

>>> a = [[]]*10
>>> a
[[], [], [], [], [], [], [], [], [], []]
>>> a[0].append(0)
>>> a
[[0], [0], [0], [0], [0], [0], [0], [0], [0], [0]]
>>> 

Como puede ver, cada elemento apunta al mismo objeto de lista. Para evitar esto, puede crear un método que inicializará cada posición a una referencia de objeto diferente.

def init_list_of_objects(size):
    list_of_objects = list()
    for i in range(0,size):
        list_of_objects.append( list() ) #different object reference each time
    return list_of_objects


>>> a = init_list_of_objects(10)
>>> a
[[], [], [], [], [], [], [], [], [], []]
>>> a[0].append(0)
>>> a
[[0], [], [], [], [], [], [], [], [], []]
>>> 

Es probable que haya una forma predeterminada de hacerlo en Python (en lugar de escribir una función), pero no estoy seguro de qué es. Estaría feliz de ser corregido!

Editar: es [ [] for _ in range(10)]

Ejemplo:

>>> [ [random.random() for _ in range(2) ] for _ in range(5)]
>>> [[0.7528051908943816, 0.4325669600055032], [0.510983236521753, 0.7789949902294716], [0.09475179523690558, 0.30216475640534635], [0.3996890132468158, 0.6374322093017013], [0.3374204010027543, 0.4514925173253973]]

19
Escuché que usar appendmuy a menudo es inferior a la lista de comprensiones. Puede crear su lista de listas a través de [ [] for _ in range(10)].
M.Herzkamp

10
Voté porque me estaba enojando porque tenía una matriz multidimensional con los mismos datos repetidos varias veces y no podía entender lo que estaba sucediendo antes de finalmente encontrar esta respuesta. ^^ No entiendo por qué es tan bajo aquí.
Bregalad

19

Puede .append(element)a la lista, por ejemplo: s1.append(i). Lo que está intentando hacer actualmente es acceder a un elemento ( s1[i]) que no existe.


16

Hay dos métodos "rápidos":

x = length_of_your_list
a = [None]*x
# or
a = [None for _ in xrange(x)]

Parece que [None]*xes más rápido:

>>> from timeit import timeit
>>> timeit("[None]*100",number=10000)
0.023542165756225586
>>> timeit("[None for _ in xrange(100)]",number=10000)
0.07616496086120605

Pero si está de acuerdo con un rango (por ejemplo [0,1,2,3,...,x-1]), entonces range(x)podría ser más rápido:

>>> timeit("range(100)",number=10000)
0.012513160705566406

Tenga en cuenta que en Python3 tendrá que usarlo list(range(n)), ya range()que no devuelve una lista pero es un iterador, y eso no es más rápido que [None] * n.
Skillmon le gusta topanswers.xyz

10

Me sorprende que nadie sugiera este enfoque simple para crear una lista de listas vacías. Este es un hilo viejo, pero solo agrega esto para completarlo. Esto creará una lista de 10 listas vacías.

x = [[] for i in range(10)]

77
La diferencia más importante entre hacer lo anterior y hacer x = [[]] * 10es que en este último, cada elemento de la lista apunta al MISMO objeto de la lista . Entonces, a menos que simplemente desee 10 copias del mismo objeto, use la rangevariante basada ya que crea 10 objetos nuevos . Encontré esta distinción muy importante.
Mandeep Sandhu

6

(Esto fue escrito en base a la versión original de la pregunta).

Quiero crear una lista vacía (o lo que sea la mejor manera) puede contener 10 elementos.

Todas las listas pueden contener tantos elementos como desee, sujeto solo al límite de memoria disponible. El único "tamaño" de una lista que importa es la cantidad de elementos que hay actualmente en ella.

pero cuando lo ejecuto, el resultado es []

print display s1no es una sintaxis válida; según su descripción de lo que está viendo, supongo que quiso decir display(s1)y luego print s1. Para que eso se ejecute, debe haber definido previamente un global s1para pasar a la función.

Llamar displayno modifica la lista que pasa, tal como está escrita. Su código dice " s1es un nombre para cualquier cosa que se haya pasado a la función; bueno, ahora lo primero que haremos será olvidarnos de esa cosa por completo y dejar que s1comience a referirse a una nueva creación list. Ahora modificaremos eso list". Esto no tiene ningún efecto sobre el valor que pasó.

No hay ninguna razón para pasar un valor aquí. (Tampoco hay una razón real para crear una función, pero eso no viene al caso). Desea "crear" algo, por lo que ese es el resultado de su función. No se requiere información para crear lo que describe, así que no pase ninguna información. Para obtener información, hágalo return.

Eso te daría algo como:

def display():
    s1 = list();
    for i in range(0, 9):
        s1[i] = i
    return s1

El siguiente problema que notará es que su lista solo tendrá 9 elementos, porque la rangefunción omite el punto final . (Como notas al margen, []funciona igual de bien list(), el punto y coma es innecesario, s1es un nombre pobre para la variable, y solo se necesita un parámetro rangesi está comenzando desde 0). Entonces termina con

def create_list():
    result = list()
    for i in range(10):
        result[i] = i
    return result

Sin embargo, esto todavía falta la marca; rangeno es una palabra clave mágica que forma parte del lenguaje fory defes, sino que es una función. ¿Y adivina qué devuelve esa función? Así es, una lista de esos enteros. Entonces toda la función colapsa a

def create_list():
    return range(10)

y ahora ves por qué no necesitamos escribir una función nosotros mismos en absoluto; rangeya es la función que estamos buscando. Aunque, de nuevo, no hay necesidad o razón para "pre-dimensionar" la lista.


4

Una forma sencilla de crear una matriz de tamaño en 2D nutilizando comprensiones de listas anidadas:

m = [[None for _ in range(n)] for _ in range(n)]

3

Estoy un poco sorprendido de que la forma más fácil de crear una lista inicializada no esté en ninguna de estas respuestas. Simplemente use un generador en la listfunción:

list(range(9))

1
Un poco curioso en cuanto a por qué alguien comenta sobre esto todavía ... Soy un novato de Python y parece que este es el camino a seguir, pero nadie dice nada. ¿Quizás la función de rango podría ser costosa o algo así?
AFP_555

3
Este problema es que esta respuesta no crea una lista vacía según la pregunta, terminará con [0, 1, 2, 3, 4, 5, 6, 7, 8], que es lo que hace la función range (9) . Asumir que crear instancias de una lista de Nones es útil en lugar de llenarlo con números de inmediato
Spcogg el segundo

¿Por qué envolver el range(9)de list()? ¿ range(9)Ya no devuelve una lista?
Zyl

2
@Zyl rangeno es una lista, ni un generador. Es una subclase inmutable incorporada de Sequence.
Nuno André

1
@ AFP_555 Creo que la verdadera pregunta es por qué no se rechaza más, ya que realmente no responde a la pregunta y podría tener malas consecuencias no deseadas.
Eric

1

Aquí está mi código para la lista 2D en python que leería no. de filas de la entrada:

empty = []
row = int(input())

for i in range(row):
    temp = list(map(int, input().split()))
    empty.append(temp)

for i in empty:
    for j in i:
        print(j, end=' ')
    print('')

0

La respuesta aceptada tiene algunas trampas. Por ejemplo:

>>> a = [{}] * 3
>>> a
[{}, {}, {}]
>>> a[0]['hello'] = 5
>>> a
[{'hello': 5}, {'hello': 5}, {'hello': 5}]
>>> 

Entonces cada diccionario se refiere al mismo objeto. Lo mismo es cierto si inicializa con matrices u objetos.

Podrías hacer esto en su lugar:

>>> b = [{} for i in range(0, 3)]
>>> b
[{}, {}, {}]
>>> b[0]['hello'] = 6
>>> b
[{'hello': 6}, {}, {}]
>>> 

-2

Encontré esta pregunta SO mientras buscaba un problema similar. Tuve que construir una matriz 2D y luego reemplazar algunos elementos de cada lista (en una matriz 2D) con elementos de un dict. Luego me encontré con esta pregunta SO que me ayudó, tal vez esto ayude a otros principiantes a moverse. El truco clave fue inicializar la matriz 2D como una matriz numpy y luego usarla en array[i,j]lugar de array[i][j].

Como referencia, este es el fragmento de código donde tuve que usar esto:

nd_array = []
for i in range(30):
    nd_array.append(np.zeros(shape = (32,1)))
new_array = []
for i in range(len(lines)):
    new_array.append(nd_array)
new_array = np.asarray(new_array)
for i in range(len(lines)):
    splits = lines[i].split(' ')
    for j in range(len(splits)):
        #print(new_array[i][j])
        new_array[i,j] = final_embeddings[dictionary[str(splits[j])]-1].reshape(32,1)

Ahora sé que podemos usar la comprensión de la lista, pero por simplicidad estoy usando un bucle for anidado. Espero que esto ayude a otros que se encuentran con esta publicación.


-2

Hazlo más reutilizable como una función.

def createEmptyList(length,fill=None):
    '''
    return a (empty) list of a given length
    Example:
        print createEmptyList(3,-1)
        >> [-1, -1, -1]
        print createEmptyList(4)
        >> [None, None, None, None]
    '''
    return [fill] * length

-3
s1 = []
for i in range(11):
   s1.append(i)

print s1

Para crear una lista, solo use estos corchetes: "[]"

Para agregar algo a una lista, use list.append ()


-3

Este código genera una matriz que contiene 10 números aleatorios.

import random
numrand=[]
for i in range(0,10):
   a = random.randint(1,50)
   numrand.append(a)
   print(a,i)
print(numrand)

3
Bienvenido a SO. Su respuesta realmente no aborda la pregunta específicamente. Eche un vistazo a stackoverflow.com/help/how-to-answer
Nick
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.