[解決済み] Pythonでコピーを生成せずにリストをスライスする
質問
次のような問題があります。
整数のリストが与えられたとき
L
があるとき、すべてのサブリストL[k:]
for k in [0, len(L) - 1]
, コピーを生成することなく .
Pythonでこれを達成するにはどうすればよいですか?どうにかしてバッファオブジェクトで?
どのように解決するには?
短い答え
リストをスライスしても、リスト内のオブジェクトのコピーは生成されず、それらへの参照がコピーされるだけです。それが質問されたことに対する答えです。
長い答え
変更可能な値と変更不可能な値に対するテスト
まず、基本的な主張を検証してみましょう。整数のような不変のオブジェクトの場合でも、参照だけがコピーされることを示すことができます。ここに3つの異なる整数オブジェクトがあり、それぞれ同じ値を持っています。
>>> a = [1000 + 1, 1000 + 1, 1000 + 1]
これらは同じ値を持っていますが、それぞれ異なる
id
s:
>>> map(id, a)
[140502922988976, 140502922988952, 140502922988928]
それらをスライスしても、参照は同じままです。新しいオブジェクトは作成されていません。
>>> b = a[1:3]
>>> map(id, b)
[140502922988952, 140502922988928]
同じ値で異なるオブジェクトを使用することは、コピー処理が を介することなく -- を気にせず、ただ直接参照をコピーしていることがわかります。
mutableな値でテストしても、同じ結果になります。
>>> a = [{0: 'zero', 1: 'one'}, ['foo', 'bar']]
>>> map(id, a)
[4380777000, 4380712040]
>>> map(id, a[1:]
... )
[4380712040]
残りのメモリのオーバーヘッドを調べる
もちろん、リファレンス 自体 はコピーされます。64 ビットのマシンでは、それぞれ 8 バイトのコストがかかります。そして各リストは 72 バイトのそれ自身のメモリ オーバーヘッドを持ちます。
>>> for i in range(len(a)):
... x = a[:i]
... print('len: {}'.format(len(x)))
... print('size: {}'.format(sys.getsizeof(x)))
...
len: 0
size: 72
len: 1
size: 80
len: 2
size: 88
ジョー・ピンソノーとして は私たちを思い起こさせます。 というように、このオーバーヘッドが加算されます。また、整数オブジェクト自体はそれほど大きくなく、参照の 3 倍程度の大きさです。そのため、絶対的な意味ではメモリを節約できますが、漸近的には、同じメモリに複数のリストを "view"できるようにするのがよいかもしれません。
ビューを使用したメモリの節約
残念ながら、Pythonはリストに"view"されたオブジェクトを生成する簡単な方法を提供しません。というか、quot;fortunately" と言うべきかもしれません! これは、スライスがどこから来たかを気にする必要がないことを意味します; オリジナルへの変更はスライスに影響を与えません。全体として、これはプログラムの動作に関する推論をより簡単にします。
ビューで作業することで本当にメモリを節約したいのであれば
numpy
配列の使用を検討してください。をスライスすると
numpy
配列のスライスでは、メモリはスライスと元の配列の間で共有されます。
>>> a = numpy.arange(3)
>>> a
array([0, 1, 2])
>>> b = a[1:3]
>>> b
array([1, 2])
を変更するとどうなるか?
a
を修正して、もう一度
b
?
>>> a[2] = 1001
>>> b
array([ 1, 1001])
しかし、これは、あるオブジェクトを修正するときに、不注意で別のオブジェクトを修正しないことを確認しなければならないことを意味します。これは
numpy
を使うときのトレードオフです。コンピュータの仕事は減り、プログラマーの仕事は増えます。
関連
-
[解決済み] リストのリストからフラットなリストを作るには?
-
[解決済み] リスト内のアイテムのインデックスを検索する
-
[解決済み] PandasでDataFrameの行を反復処理する方法
-
[解決済み] リストが空かどうかを確認するにはどうすればよいですか?
-
[解決済み] ファイルのコピー方法について教えてください。
-
[解決済み] 最小限の驚き」と「変更可能なデフォルトの引数
-
[解決済み] Python 3で「1000000000000000 in range(1000000000000001)」はなぜ速いのですか?
-
[解決済み】Pythonに三項条件演算子はありますか?
-
[解決済み] Jupyterノートブックでenv変数を設定する方法
-
[解決済み] virtualenv の `--no-site-packages` オプションを元に戻す。
最新
-
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 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み] 前月の日時オブジェクトを返す
-
[解決済み] Pandasのデータフレームでタプルの列を分割するにはどうしたらいいですか?
-
[解決済み] PythonでSVGからPNGに変換する
-
[解決済み] googletransがエラー 'NoneType' オブジェクトに 'group' 属性がない、と言って動かなくなった。
-
[解決済み] Pythonのargparseを使った隠し引数の作成
-
[解決済み] 異なる順序で同じ要素を持つ2つのJSONオブジェクトを等しく比較するには?
-
[解決済み] virtualenvsはどこに作成するのですか?
-
[解決済み] djangoのQueryDictをPythonのDictに変更するには?
-
[解決済み] pipの依存性/必要条件をリストアップする方法はありますか?
-
[解決済み] Python文字列インターン