¿Por qué “x = x.append(…)” no funciona en un bucle for?

4 minutos de lectura

Avatar de usuario de LostLin
LostLin

Estoy tratando de agregar objetos al final de una lista repetidamente, así:

list1 = []
n = 3
for i in range(0, n):
    list1 = list1.append([i])

Pero me sale un error como: AttributeError: 'NoneType' object has no attribute 'append'. ¿Esto se debe a que list1 comienza como una lista vacía? ¿Cómo soluciono este error?


Esta pregunta es específicamente sobre cómo solucionar el problema y agregarlo a la lista correctamente. En el código original, el error informado ocurre cuando se usa un bucle porque .append devoluciones None la primera vez. Para por qué None se devuelve (la decisión de diseño subyacente), consulte ¿Por qué estas operaciones de lista devuelven Ninguno, en lugar de la lista resultante?

si tienes un IndexError de intentar asignar a un índice justo después del final de una lista, eso no funciona; necesitas el .append método en su lugar. Para obtener más información, consulte ¿Por qué este código iterativo de crecimiento de listas genera IndexError: el índice de asignación de listas está fuera de rango? ¿Cómo puedo agregar repetidamente elementos a una lista?.

Si desea agregar lo mismo valor varias veces, consulte Python: Agregar elemento a la lista N veces.

  • No -1 por favor. El hecho de que append() devuelva None puede engañar a los principiantes. La pregunta es genuina.

    – e-satis

    14 de junio de 2011 a las 7:26

  • En lugar de usar un bucle para .append cada vez es más simple y eficiente simplemente .extend con todos los valores: list1.extend(range(n)) – no se necesita bucle. Sin embargo, la pregunta no es realmente sobre el ciclo, eso fue lo que convirtió el problema de regresar None en una excepción real. Consulte también stackoverflow.com/questions/6039605 (solo relacionado tangencialmente).

    – Karl Knechtel

    3 ago a las 23:43


  • No marqué esto como un duplicado porque la tarea subyacente, que se agrega repetidamente a una lista, merece consideración por sí sola. Sin embargo, la mayoría de las preguntas sobre .append estará mejor cerrado como un duplicado del otro canónico.

    – Karl Knechtel

    14 de septiembre a las 12:29

Avatar de usuario de Andrew Jaffe
andres jaffe

append Realmente cambios la lista. Además, se necesita un artículo, no una lista. Por lo tanto, todo lo que necesita es

for i in range(n):
   list1.append(i)

(Por cierto, tenga en cuenta que puede usar range(n)en este caso.)

Supongo que su uso real es más complicado, pero es posible que pueda usar una lista de comprensión, que es más pitónica para esto:

list1 = [i for i in range(n)]

O, en este caso, en Python 2.x range(n) de hecho, ya crea la lista que desea, aunque en Python 3.x, necesita list(range(n)).

  • gracias, lo último fue muy útil y acortó mi código por un montón

    – LostLin

    14 de junio de 2011 a las 15:45

  • @AndrewJaffe, ¿qué pasa con una lista de listas?

    – Py-ser

    15 de mayo de 2014 a las 9:12

  • Depende de lo que quieras hacer. append agrega a la lista más externa, pero puede agregar a una lista anidada indexándola: a[-1].append(3) agrega 3 a la última sublista de a.

    – Andrew Jaffe

    15 mayo 2014 a las 11:27

Avatar de usuario de Mikola
Mikola

No necesita el operador de asignación. agregar devuelve Ninguno.

append devuelve Ninguno, por lo que en la segunda iteración está llamando al método append de NingunoTipo. Simplemente elimine la tarea:

for i in range(0, n):
    list1.append([i])

Mikola tiene la respuesta correcta pero un poco más de explicación. Se ejecutará la primera vez, pero debido a que append devuelve Nonedespués de la primera iteración del ciclo for, su asignación causará list1 A igual None y por lo tanto, el error se arroja en la segunda iteración.

yo personalmente prefiero el + operador que append:

for i in range(0, n):

    list1 += [[i]]

Pero esto crea una nueva lista cada vez, por lo que podría no ser lo mejor si el rendimiento es crítico.

Avatar de usuario de Artsiom Rudzenka
Artsiom Rudzenka

Tenga en cuenta que también puede usar insertar para colocar el número en la posición requerida dentro de la lista:

initList = [1,2,3,4,5]
initList.insert(2, 10) # insert(pos, val) => initList = [1,2,10,3,4,5]

Y también tenga en cuenta que en python siempre puede obtener una lista de longitud usando el método len()

Avatar de usuario de John
John

Como dijo Mikola, append() devuelve un vacío, por lo que cada iteración está configurando list1 en un tipo nulo porque append devuelve un tipo nulo. En la próxima iteración, list1 es nulo, por lo que está intentando llamar al método de adición de un valor nulo. Los nulos no tienen métodos, de ahí su error.

¿Ha sido útil esta solución?