He visto que en realidad hay dos (tal vez más) formas de concatenar listas en Python: una es usar el método extend ():
a = [1, 2]
b = [2, 3]
b.extend(a)
el otro para usar el operador más (+):
b += a
Ahora me pregunto: ¿Cuál de esas dos opciones es la forma 'pitónica' de hacer la concatenación de listas? ¿Hay alguna diferencia entre las dos? (He buscado el tutorial oficial de Python pero no pude encontrar nada sobre este tema)
.__iadd__()
/.__add__()
/.__radd__()
versus.extend()
Respuestas:
La única diferencia en un nivel de código de bytes es que la
.extend
forma involucra una llamada a la función, que es un poco más costosa en Python que elINPLACE_ADD
.Realmente no es nada de lo que deba preocuparse, a menos que realice esta operación miles de millones de veces. Sin embargo, es probable que el cuello de botella se encuentre en otro lugar.
fuente
.__iadd__()
/.__add__()
/.__radd__()
versus.extend()
No puede usar + = para una variable no local (variable que no es local para la función y tampoco global)
Es porque para el caso extendido , el compilador cargará la variable
l
usandoLOAD_DEREF
instrucciones, pero para + = usaráLOAD_FAST
, y obtendrá*UnboundLocalError: local variable 'l' referenced before assignment*
fuente
Puede encadenar llamadas de función, pero no puede + = una llamada de función directamente:
fuente
Diría que hay alguna diferencia cuando se trata de numpy (acabo de ver que la pregunta es acerca de la concatenación de dos listas, no la matriz numpy, pero dado que podría ser un problema para principiantes, como yo, espero que esto pueda ayudar a alguien quienes buscan la solución a este post), por ej.
volverá con error
ValueError: los operandos no se pudieron transmitir junto con las formas (0,) (4,4,4)
b.extend(a)
funciona perfectamentefuente
Desde el código fuente de CPython 3.5.2 : No hay gran diferencia.
fuente
extend () funciona con cualquier iterable *, + = funciona con algunos pero puede volverse funky.
Python 3.6
* bastante seguro .extend () funciona con cualquier iterable pero comente si soy incorrecto
fuente
list.extend(iterable) Extend the list by appending all the items from the iterable. Equivalent to a[len(a):] = iterable.
Supongo que respondí mi propio asterisco.+=
operador con objetos de diferentes tipos (al contrario de dos listas, como en la pregunta), no puede esperar obtener una concatenación de los objetos. Y no puede esperar que haya unlist
tipo devuelto. Eche un vistazo a su código, obtendrá un ennumpy.ndarray
lugar delist
.En realidad, existen diferencias entre las tres opciones:
ADD
,INPLACE_ADD
yextend
. El primero siempre es más lento, mientras que los otros dos son más o menos lo mismo.Con esta información, preferiría usar
extend
, que es más rápidoADD
y me parece más explícito de lo que está haciendo queINPLACE_ADD
.Pruebe el siguiente código varias veces (para Python 3):
fuente
ADD
conINPLACE_ADD
yextend()
.ADD
produce una nueva lista y copia los elementos de las dos listas originales. Seguro que será más lento que la operación in situ deINPLACE_ADD
yextend()
.Esta información está oculta en las Preguntas frecuentes sobre programación :
También puede ver esto por sí mismo en el código fuente de CPython: https://github.com/python/cpython/blob/v3.8.2/Objects/listobject.c#L1000-L1011
fuente
De acuerdo con Python para el análisis de datos.
“Tenga en cuenta que la concatenación de listas por adición es una operación relativamente costosa ya que se debe crear una nueva lista y copiar los objetos. Por lo general, es preferible utilizar extender para agregar elementos a una lista existente, especialmente si está creando una lista grande. "Por lo tanto,
es más rápido que la alternativa concatenativa:
fuente
everything = everything + temp
no se implementa necesariamente de la misma manera queeverything += temp
.everything += temp
se implementa de tal manera queeverything
no es necesario copiarlo. Esto hace que su respuesta sea un punto discutible.