なぜPythonはシーケンスに対して範囲外のスライスインデックスを許すのですか?
質問
私はちょうどPythonの奇妙な機能のように思えるものに出くわしたので、それについていくつかの明確化を望んでいました。
次の配列操作は、いくらか意味があります。
p = [1,2,3]
p[3:] = [4]
p = [1,2,3,4]
実際にはこの値を最後に追加しているだけだと想像しますが、いかがでしょうか?
しかしながら、なぜこのようなことができるのでしょうか?
p[20:22] = [5,6]
p = [1,2,3,4,5,6]
そして、さらにこんなことも。
p[20:100] = [7,8]
p = [1,2,3,4,5,6,7,8]
これは間違ったロジックのように思えます。これはエラーを投げるべきように思えます!
何か説明がありますか?
-それはちょうどPythonが行う奇妙なことですか?
-何か目的があるのでしょうか?
-それとも、私の考え方が間違っているのでしょうか?
どのように解決するのですか?
範囲外の指数に関する質問の一部
スライスロジックは自動的にインデックスをシーケンスの長さに合わせて切り取ります。
スライスインデックスが終点を超えて拡張することを許可するのは、利便性のために行われました。 すべての式を範囲チェックして、手動で制限を調整しなければならないのは面倒なので、Pythonがあなたのためにそれを行います。
テキストメッセージの最初の50文字より多くを表示したくないというユースケースを考えてみましょう。
簡単な方法(Pythonが今やっていること)。
preview = msg[:50]
または、難しい方法(自分でリミットチェックをする)。
n = len(msg)
preview = msg[:50] if n > 50 else msg
終点の調整のためにそのロジックを手動で実装することは、忘れやすく、間違えやすく(2か所で50を更新する)、言葉が多くなり、遅くなります。 Pythonはそのロジックを内部に移動させ、簡潔で、自動的で、速く、そして正しいものにします。 これは私がPythonを愛する理由の1つです:-)
入力の長さからの代入の長さの不一致に関する質問の部分
OP はまた、次のような割り当てを許可する根拠を知りたがっていました。
p[20:100] = [7,8]
のような割り当てを許可する根拠についても知りたいと考えていました。
文字列との類似によって動機を見るのが最も簡単です。 考えてみましょう。
"five little monkeys".replace("little", "humongous")
. ターゲットの "little" は6文字しかなく、 "humongous" は9文字であることに注意してください。 リストでも同じことができます。
>>> s = list("five little monkeys")
>>> i = s.index('l')
>>> n = len('little')
>>> s[i : i+n ] = list("humongous")
>>> ''.join(s)
'five humongous monkeys'
これはすべて利便性のためです。
が導入される以前は copy() と clear() メソッドがあり、これらは以前はよく使われたイディオムでした。
s[:] = [] # clear a list
t = u[:] # copy a list
現在でも、フィルタリングの際にリストを更新するために使用しています。
s[:] = [x for x in s if not math.isnan(x)] # filter-out NaN values
これらの実用例が、なぜスライスが機能するのかについて良い見通しを与えてくれることを願っています。
関連
-
[解決済み] Python 3で「1000000000000000 in range(1000000000000001)」はなぜ速いのですか?
-
[解決済み] pandasを使った "大量データ "ワークフロー【終了しました
-
[解決済み] なぜPythonのコードは関数の中でより速く実行されるのですか?
-
[解決済み] なぜpythonはforやwhileループの後に'else'を使うのですか?
-
[解決済み] ディレクトリ内のすべてのPythonユニットテストを実行するにはどうすればよいですか?
-
[解決済み】range(start, end)にendが含まれないのはなぜ?
-
[解決済み] Djangoで2つの日付の間を選択する
-
[解決済み] DataFrameに日付間の日数カラムを追加する pandas
-
[解決済み] PythonからSMTPを使用してメールを送信する
-
[解決済み] PythonのRequestsモジュールを使ってWebサイトに "ログイン "するには?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み] Jupyterノートブックでenv変数を設定する方法
-
[解決済み] Pythonの構文に新しいステートメントを追加することはできますか?
-
[解決済み] pandasのDataFrameから空のセルを含む行を削除する
-
[解決済み] Python 2.7サポート終了?
-
[解決済み] Django 1.7で初期マイグレーションからマイグレートバックする方法は?
-
[解決済み] Flask でグローバル変数はスレッドセーフか?リクエスト間でデータを共有するには?
-
[解決済み] djangoフレームワークでフォームフィールドから値を取得するには?
-
[解決済み] pycharmがタブをスペースに自動変換する
-
[解決済み] Pythonの検索パスを他のソースに展開する
-
[解決済み] あるメソッドが複数の引数のうち1つの引数で呼び出されたことを保証する