python / python/cpython

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

Ouverte
#138,357 9 commentaires 0 réactions 0 personnes assignées Voir sur GitHub

Personne n'a encore pris cette issue.

interpreter-core type-feature
Langage dominant
Python
Étoiles
77.2k
Forks
36k
Métriques de merge des PR
Métriques de PR en attente

Description

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

Guide de contribution

Ouvrir le guide de contribution

Par où commencer

  1. Lisez l'issue en entier, puis le guide de contribution du projet.
  2. Signalez en commentaire que vous la prenez — cela évite que deux personnes fassent le même travail.
  3. Forkez le dépôt et travaillez sur une branche.
  4. Ouvrez une pull request qui référence le numéro de l'issue.

Piste de recherche

Commencez par reproduire dans un interpréteur Python les exemples d’affectation de slices avec des pas positifs et négatifs, puis comparez leur comportement actuel. Examinez l’implémentation de l’affectation de slices de listes et les tests pertinents, puis vérifiez que step -1 autorise des longueurs différentes pour l’itérable et le slice, tout en préservant le résultat proposé et les règles existantes des slices étendus.

Rédigé par le modèle d'indexation à partir du texte de l'issue.

Évaluation

Stack technique
python
Domaine
backend
Type d'issue
Fonctionnalité
Difficulté
5/5
Temps estimé
Plus d'une semaine
Activité
À l'abandon
Clarté
Clairement spécifiée
Accessibilité débutants
35/100

Recevez les nouvelles issues par e-mail

Un résumé court des issues GitHub adaptées aux débutants.