python / python/cpython

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

オープン
#138,357 コメント 9 件 リアクション 0 件 担当者 0 名 GitHub で見る

まだ誰も着手していません。

interpreter-core type-feature
主要言語
Python
スター
77.2k
フォーク
36k
PR マージ指標
PR 指標を取得中

説明

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

コントリビューションガイド

コントリビューションガイドを開く

はじめの一歩

  1. issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
  2. 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
  3. リポジトリをフォークし、ブランチを切って変更します。
  4. issue 番号を参照したプルリクエストを送ります。

調査の方向性

まず、正のステップと負のステップを使ったスライス代入の例を Python インタープリターで再現し、現在の動作を比較します。リストのスライス代入の実装と関連するテストを調査し、その後、step -1 では iterable と slice の長さが異なる場合も許可され、提案された結果と既存の extended-slice の規則が維持されることを確認します。

索引モデルが issue の本文から書いたものです。

評価

技術スタック
python
領域
backend
issue の種類
機能追加
難易度
5/5
見積もり時間
1週間以上
活発さ
停滞
明瞭さ
明確に書かれている
初心者へのやさしさ
35/100

新しい issue をメールで受け取る

初心者向けの GitHub issue を短くまとめたダイジェスト。