python / python/cpython

Assigning to a slice of a list with a step of -1 should permit assigning a different number of items

Abierto
#138,357 9 comentarios 0 reacciones 0 asignados Ver en GitHub

Nadie ha tomado este issue todavía.

interpreter-core type-feature
Lenguaje dominante
Python
Estrellas
77.2k
Forks
35.9k
Métricas de merge de PR
Métricas de PR pendientes

Descripción

Feature or enhancement

Proposal:

(Note: this behavior is so old, I'd be surprised if genuinely nobody had ever suggested it before. So I give it a 30% chance it's actually a bad idea for some reason I've missed. Nevertheless--let's give it a go.)

In Python, you can assign to a slice of a list. The right hand side must be an iterable, and the values it yields replace the corresponding elements of the list:

>>> l = [1, 2, 3, 4, 5]
>>> l[1:4] = 'abc'
>>> l
[1, 'a', 'b', 'c', 5]

For a non-extended slice, where step is either None or 1, the number of items yielded by the iterable and the length of the slice don't need to agree. The list object will happily replace the sliced elements with all the elements of the iterable:

>>> l = [1, 2, 3, 4, 5]
>>> l[1:4] = 'abcdef'
>>> l
[1, 'a', 'b', 'c', 'd', 'e', 'f', 5]

You can also assign to an extended slice, defined as any slice with a step != 1:

>>> l = [1, 2, 3, 4, 5]
>>> l[0:5:2] = 'abc'
>>> l
['a', 2, 'b', 4, 'c']

But when step is != 1, the number of elements yielded by the iterable and the length of the slice must agree:

>>> l = [1, 2, 3, 4, 5]
>>> l[0:5:2] = 'abcdef'
ValueError: attempt to assign sequence of size 6 to extended slice of size 3

If you assign to a slice with a negative step, it actually assigns the values in reverse:

>>> l = [1, 2, 3, 4, 5]
>>> l[3:0:-1] = 'abc'
>>> l
[1, 'c', 'b', 'a', 5]

But a step of -1 means this is an "extended" slice, so the list object requires the size of the iterable and the length of the slice to agree:

>>> l = [1, 2, 3, 4, 5]
>>> l[3:0:-1] = 'abcdef'
ValueError: attempt to assign sequence of size 6 to extended slice of size 3

I think this is a flaw. I claim that

>>> l = [1, 2, 3, 4, 5]
>>> l[1:4] = 'abcdef'

and

>>> l = [1, 2, 3, 4, 5]
>>> l[3:0:-1] = reversed('abcdef')

should produce identical results; they should both set l to [1, 'a', 'b', 'c', 'd', 'e', 'f', 5].

In summary: Python should permit assigning an iterable to a slice where the iterable and slice are of different magnitudes if step is 1 or -1.

Has this already been discussed elsewhere?

This is a minor feature, which does not need previous discussion elsewhere

Links to previous discussion of this feature:

No response

Guía de contribución

Abrir la guía de contribución

Primeros pasos

  1. Lee el issue completo y luego la guía de contribución del proyecto.
  2. Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
  3. Haz un fork del repositorio y trabaja en una rama.
  4. Abre un pull request que haga referencia al número del issue.

Línea de trabajo

Empieza reproduciendo en un intérprete de Python los ejemplos de asignación de slices con pasos positivos y negativos, y compara su comportamiento actual. Investiga la implementación de la asignación de slices de listas y las pruebas relevantes; después verifica que step -1 permite longitudes diferentes del iterable y del slice, manteniendo el resultado propuesto y las reglas existentes para slices extendidos.

Escrito por el modelo de indexación a partir del texto del issue.

Evaluación

Stack tecnológico
python
Área
backend
Tipo de issue
Nueva funcionalidad
Dificultad
5/5
Tiempo estimado
Más de una semana
Estado de actividad
Estancado
Claridad
Bien especificado
Aptitud para principiantes
35/100

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.