• Jobs
  • About Us
  • professionals
    • Home
    • Jobs
    • Courses and challenges
  • business
    • Home
    • Post vacancy
    • Our process
    • Pricing
    • Assessments
    • Payroll
    • Blog
    • Sales
    • Salary Calculator

0

178
Views
Asignación simultánea indexando diferentes elementos de la lista en Python
>>arr = [4, 2, 1, 3] >>arr[0], arr[arr[0]-1] = arr[arr[0]-1], arr[0] >>arr

Resultado que espero >>[3, 2, 1, 4]

Resultado que obtengo >>[3, 2, 4, 3]

Básicamente, estoy tratando de intercambiar el n. ° 4 y el n. ° 3 (en mi problema real, el índice no será 0, sino un iterador "i". Así que no puedo simplemente hacer arr[0], arr[3] = arr[ 3], arr[0]) Pensé que entendía bastante bien la asignación simultánea. Aparentemente estaba equivocado. No entiendo por qué arr[arr[0]-1] en el lado izquierdo de la tarea se evalúa como arr[2] en lugar de arr[3]. Si las asignaciones ocurren simultáneamente (evaluado desde la derecha),

arr[0] (dentro del índice del segundo elemento a la izquierda) aún debe ser "4"

arr[0] -1 (el índice del segundo elemento a la izquierda) debería ser "3"

over 3 years ago · Santiago Trujillo
3 answers
Answer question

0

Porque la lista de objetivos no se evalúa simultáneamente . Aquí está la sección relevante de los documentos:

El objeto debe ser iterable con el mismo número de elementos que objetivos en la lista de objetivos, y los elementos se asignan, de izquierda a derecha, a los objetivos correspondientes.

Dos cosas a tener en cuenta, el lado derecho evalúa primero la expresión. Entonces, en el RHS, primero creamos la tupla:

 (3, 4)

Tenga en cuenta que eso se hace de izquierda a derecha . Ahora, la asignación a cada objetivo en la lista de objetivos de la izquierda se realiza en orden:

 arr[0] = 3

Luego, el siguiente objetivo, arr[0] es 3 y 3-1 es 2

 arr[2] = 4

Entonces, una solución simple es simplemente calcular los índices primero antes del intercambio:

 >>> arr = [4, 2, 1, 3] >>> i, j = arr[0] - 1, 0 >>> arr[j], arr[i] = arr[i], arr[j] >>> arr [3, 2, 1, 4]

Aquí hay una demostración usando una lista detallada que podemos definir fácilmente:

 >>> class NoisyList(list): ... def __getitem__(self, item): ... value = super().__getitem__(item) ... print("GETTING", item, "value of", value) ... return value ... def __setitem__(self, item, value): ... print("SETTING", item, 'with', value) ... super().__setitem__(item, value) ... >>> arr = NoisyList([4, 2, 1, 3]) >>> arr[0], arr[arr[0]-1] = arr[arr[0]-1], arr[0] GETTING 0 value of 4 GETTING 3 value of 3 GETTING 0 value of 4 SETTING 0 with 3 GETTING 0 value of 3 SETTING 2 with 4
over 3 years ago · Santiago Trujillo Report

0

Ok, esto sucede porque el arr[0] se cambia a 3 cuando le asignas arr[arr[0]-1] . Y después de eso, cuando Python echa un vistazo a arr[arr[0]-1] e intenta asignarle el valor de arr[0] si encuentra que arr[0] es 3 porque en la asignación anterior lo ha cambiado. Una pequeña demostración:

 arr = [4, 2, 1, 3] arr[0], arr[arr[0]-1] = arr[arr[0]-1], arr[0] │ │ └──────────┬────────────────┘ │ │ these are done first and the list becomes: [3, 2, 1, 3] Next when the python takes a look at these two, it: │ ┌────────────┴───────────────┐ │ │ arr[0], arr[arr[0]-1] = arr[arr[0]-1], arr[0] it finds the `arr[0]` to be `3` so, it assigns `3` to the `3rd` element because `arr[arr[0]-1]` is 3.
over 3 years ago · Santiago Trujillo Report

0

La sustitución de los dos valores no es verdaderamente simultánea; se manejan en orden de izquierda a derecha. Entonces, alterar arr durante ese proceso conduce a este comportamiento.

Considere este ejemplo alternativo:

 >>> arr = [1, 2, 3] >>> arr[0], arr[arr[0]] = 10, 5 ...

Con una reasignación simultánea hipotética, tratamos de reemplazar el primer valor de arr con 10 y luego el elemento arr[0] 1 ( también conocido como 1st ) con 5 . Entonces, con suerte , obtenemos [10, 5, 3] . Pero esto falla con IndexError: list assignment index out of range . Si luego inspecciona arr después de este error:

 >>> arr [10, 2, 3]

La primera tarea se completó, pero la segunda fracasó. Cuando se trata de la segunda asignación (después de la coma), no se puede encontrar el valor real arr[0] th (también conocido como 10 ) (b/c la lista no es tan larga).

Este comportamiento también se puede ver especificando claramente que la segunda asignación falle (todavía especificando un índice fuera de rango):

 >>> arr = [1, 2, 3] >>> arr[0], arr[99] = 5, 6 # Same index error, but arr becomes [5, 2, 3]

Esto recuerda a modificar una lista sobre la que está iterando , lo que a veces es factible pero a menudo se desaconseja porque genera problemas como lo que está viendo.

Una alternativa es crear una copia (esta es a veces una solución para modificar la lista sobre la que está iterando) y usarla para hacer referencia a los valores en arr :

 >>> arr = [4, 2, 1, 3] >>> copy = arr.copy() >>> arr[0], arr[copy[0]-1] = copy[copy[0]-1], copy[0] >>> arr [3, 2, 1, 4]

Aunque es bastante feo aquí. La alternativa en la respuesta aceptada es mucho mejor, ¡o este enfoque idiomático probablemente también debería funcionar!

over 3 years ago · Santiago Trujillo Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Our process Sales
Legal
Terms and conditions Privacy policy
© 2025 PeakU Inc. All Rights Reserved.

Andres GPT

Recommend me some offers
I have an error