En los primeros días de trabajar como programador de Python, todos encontramos diferentes tipos de errores en nuestro código, que después de algunas horas dolorosas en StackOverflow no son un error, sino características de Python. A continuación se presentan los 5 errores más comunes que cometen la mayoría de los nuevos programadores de Python. Averigüemos un poco sobre ellos para ahorrar varias horas haciendo preguntas en páginas y grupos en Facebook.
1. Copiar diccionarios o listas
Cuando necesite hacer una copia de un diccionario o una lista, simplemente usar el operador de asignación no es suficiente.
Equivocado:>>> dict_a = {"name": "John", "address":"221B Baker street"} >>> dict_b = dict_a
Ahora, si cambia o actualiza dict_b, entonces dict_a también cambiará, y todo esto gracias al operador de asignación. Con este operador, intenta decir que dict_b apuntará al mismo objeto que dict_a.
>>> dict_b["age"] = 26 >>> dict_b {'address': '221B Baker street', 'name': 'John', 'age': 26} >>> dict_a {'address': '221B Baker street', 'name': 'John', 'age': 26} >>>
Correcto: use los métodos copy () o deepcopy ().
>>> dict_c = dict_b.copy() >>> dict_c["location"] = "somewhere" >>> dict_c {'address': '221B Baker street', 'name': 'John', 'age': 26, 'location': 'somewhere'} >>> dict_b {'address': '221B Baker street', 'name': 'John', 'age': 26} >>> dict_a {'address': '221B Baker street', 'name': 'John', 'age': 26} >>>
Vea la diferencia entre copia y copia profunda.2. Teclas del diccionario
Intentemos agregar valores al diccionario:
>>> dict_a = dict() >>> dict_a {} >>> dict_a[1] = "apple" >>> dict_a[True] = "mango" >>> dict_a[2] = "melon"
Si intentamos mostrar el diccionario en la pantalla, ¿qué veremos?
>>> dict_a {1: 'mango', 2: 'melon'}
¿Qué pasó? ¿Dónde está la clave verdadera?
Debe recordarse que la clase booleana hereda de Integer (enteros). Y un número entero equivalente a True es 1; el falso equivalente es 0. Por lo tanto, el valor de la clave 1 simplemente se sobrescribe.
>>> isinstance(True, int) True >>> isinstance(False, int) True >>> True == 1 True >>> False == 0 True
3. Actualización de listas o diccionarios
Suponga que desea agregar un elemento a una lista.
>>> list_a = [1,2,3,4,5] >>> list_a = list_a.append(6) >>> list_a >>>
O tratando de actualizar el diccionario.
>>> dict_a = {"a" : "b"} >>> dict_a = dict_a.update({"c" : "d"}) >>> dict_a >>>
Ahora intentemos organizar la lista.
>>> list_b = [2,5,3,1,7] >>> list_b = list_b.sort() >>> list_b >>>
¿Por qué no sale nada, qué estamos haciendo mal?
La mayoría de los métodos de contenedor (como ordenar, actualizar, agregar, agregar, etc.) están optimizados para fines de rendimiento y evitan la creación innecesaria de copias separadas.
No intente asignar el valor de retorno de tales métodos a una variable.
Correctamente: >>> list_a = [1,2,3,4,5] >>> list_a.append(6) >>> dict_a = {"a" : "b"} >>> dict_a.update({"c" : "d"}) >>> dict_a {'c': 'd', 'a': 'b'} >>> list_a.sort() >>> list_a [1, 2, 3, 4, 5, 6]
4. Cuerdas internadas
En algunos casos, Python intenta reutilizar objetos inmutables existentes. El internamiento de cadenas es uno de esos casos.
>>> a = "gmail" >>> b = "gmail" >>> a is b True
Aquí tratamos de crear dos objetos diferentes: cadenas. Pero cuando los probamos para determinar su equivalencia, resultó que coincidían por completo. Esto se debe a que Python no creó otro objeto b, sino que hizo que b señalara al primer valor de "gmail".
Todas las cuerdas de longitud 1 están internadas. Las líneas que tengan algo más que caracteres ASCII, números y guiones bajos no serán internados.
Vamos a verlo
>>> a = "@gmail" >>> b = "@gmail" >>> a is b False
También recuerde que == es diferente del operador is. El operador == verifica si los valores son equivalentes o no, mientras que el operador is verifica si ambas variables se refieren al mismo objeto.
>>> a = "@gmail" >>> b = "@gmail" >>> a is b False >>> a == b True
Así que tenga esto en cuenta cuando use cadenas inmutables o == y es operadores.
5. Los argumentos predeterminados se evalúan una vez.
Considere un ejemplo:
def func(a, lst=[]): lst.append(a) return lst print(func(1)) print(func(2))
¿Qué crees que se mostrará después de dos impresiones?
Ejecutemos el código.
>>> def func(a, lst=[]): ... lst.append(a) ... return lst ... >>> print(func(1)) [1] >>> print(func(2)) [1, 2]
¿Por qué sale el segundo caso [1, 2]? ¿No debería ser solo [2]?
Entonces, el problema es que los argumentos predeterminados se evalúan solo una vez. La primera vez que se llamó a la función, func (1), la lista se evaluó y se dio cuenta de que estaba vacía. Esto significa que puede agregar 1. Pero en la segunda llamada - func (2) - ya hay un elemento en la lista, por lo tanto, se muestra [1, 2].
Bonificación: no es necesario mezclar espacios y pestañas. Solo no lo hagas.