python / python/cpython

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

Offen
#138,357 9 Kommentare 0 Reaktionen 0 zugewiesene Personen Auf GitHub ansehen

Dieses Issue hat noch niemand übernommen.

interpreter-core type-feature
Vorherrschende Sprache
Python
Sterne
77.2k
Forks
35.9k
PR-Merge-Kennzahlen
PR-Kennzahlen ausstehend

Beschreibung

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

Beitragsleitfaden

Beitragsleitfaden öffnen

Erste Schritte

  1. Lies das ganze Issue und danach den Beitragsleitfaden des Projekts.
  2. Schreib ins Issue, dass du es übernimmst — das erspart doppelte Arbeit.
  3. Forke das Repository und arbeite in einem Branch.
  4. Öffne einen Pull Request, der die Issue-Nummer nennt.

Rechercherichtung

Beginne damit, die Beispiele für Slice-Zuweisungen mit positiven und negativen Schritten in einem Python-Interpreter nachzustellen und ihr aktuelles Verhalten zu vergleichen. Untersuche die Implementierung der Listenslice-Zuweisung und die relevanten Tests; überprüfe anschließend, dass step -1 unterschiedliche Längen von Iterable und Slice zulässt und dabei das vorgeschlagene Ergebnis sowie die bestehenden Regeln für erweiterte Slices beibehält.

Vom Indexierungsmodell aus dem Issue-Text verfasst.

Bewertung

Tech-Stack
python
Bereich
backend
Issue-Typ
Feature
Schwierigkeit
5/5
Geschätzter Aufwand
Über eine Woche
Aktivitätsstatus
Veraltet
Klarheit
Klar beschrieben
Anfängerfreundlichkeit
35/100

Neue Issues direkt in Ihr Postfach

Eine kurze Übersicht über anfängerfreundliche GitHub-Issues.