ここにいくつかのコードがあります:
li=[1,2,3]
def change(l):
l[2]=10
change(li)
print li
[1, 2, 10]
しかし、私はこれが欲しい:
li=[1,2,3]
def change(l):
l=[1,2,10]
change(li)
print li
[1,2,3]
何らかの理由で、メソッド内のリスト全体を変更する必要があります。どうすればこれを達成できますか?何か間違っているか、私の間違いですか?
ここにいくつかのコードがあります:
li=[1,2,3]
def change(l):
l[2]=10
change(li)
print li
[1, 2, 10]
しかし、私はこれが欲しい:
li=[1,2,3]
def change(l):
l=[1,2,10]
change(li)
print li
[1,2,3]
何らかの理由で、メソッド内のリスト全体を変更する必要があります。どうすればこれを達成できますか?何か間違っているか、私の間違いですか?
メソッド内のリスト全体を変更したい場合は、おそらくコピーを作成して返したいと思うでしょう:
def change(li):
new_list = li[:] #copy
new_list[2] = 10
return new_list
li = [1,2,3]
new_lst = change(li) #new_lst = [1,2,10]
リストを返したくないが、その場で変更したい場合は、スライス割り当てを使用できます (*警告: これは一般的な方法ではありません)。
def change(li):
li[:] = [1,2,10]
li = [4,5,6]
change(li)
print(li) #[1, 2, 10]
このような:
li = [1, 2, 3]
def change(l):
l[:] = [1, 2, 10]
change(li)
print li # [1, 2, 10]
あなたのアプローチがうまくいかない理由は、Python では、変数は単にオブジェクトを参照する名前であるためです。作成したばかりの新しいリストを参照するようl = [1, 2, 10]
に名前を再バインドしているl
と、古いリストは変更されず、引き続きグローバル変数によって参照されますli
。
上記のコードは代わりに、スライス割り当てl
を使用して、が指すオブジェクトを変更します。
mgilson が彼の回答で示しているように、関数が実際に渡された引数をその場で変更することを明確にする必要があります。そうでない場合、疑いを持たないプログラマーは、後でそのまま使用する予定のリストを渡して、その中のすべてが失われていることに気付くかもしれません。あなたの関数に変更を示す名前を付けて(あなたがしたように)、それから何も返さないことは、両方ともそのような関数の一般的な指標ですrandom.shuffle
。
dict に対して同じ効果を達成するために、ドキュメントはこれが行うことを教えてくれます:
def change_dict(d):
d.clear() # Empty dict
d.update({"a": 3, "b": 9})
このコードでは、 l は全体に共通のオブジェクトとして機能するため、オブジェクトのメモリ位置を提供する id() で確認できます。そのため、最後の出力 [1,2,10] が得られました。
l = [1, 2, 3]
print id(l)
def change(l):
l[:] = [1, 2, 10]
print id(l)
change(l)
print l
print id(l)
目的の出力が必要な場合は、機能するオブジェクトを提供するディープコピーを使用します。
from copy import deepcopy
l = [1, 2, 3]
print id(l)
def change(l):
l[:] = [1, 2, 10]
print id(l)
change(deepcopy(l))
print l
print id(l)
ドキュメンテーション: List Aliasing — How to Think like a Computer Scientist (第 2版)
Python のリスト エイリアシングを利用できます (これは、初心者にとってよくある落とし穴です)。
関数に渡すli
と、エイリアスが に渡されます。つまり、両方ともメモリ内の同じオブジェクトを指し、一方を変更すると他方が変更されます。しかし、そうすると、別のリストを指し、エイリアシングの魔法が失われます。これを解決するには、次のようにスライス操作を使用して完全なリストに置き換えます。change
l
li
l = [1, 2, 10]
l
li = [1, 2, 3]
def change(l):
l[:] = [1, 2, 10] # doesn't make a new list
change(li) # preserves aliasing
print li # returns [1, 2, 10]
ドキュメンテーション: ステートメント
global
— Python Docs
l
関数内で行っている変更は、li
外部のリストには適用されません。グローバルを使用して、li
変更しようとしているリストに影響を与えることができます。
li = [1, 2, 3]
def change():
global li
li = [1, 2, 10] # use this
li[2] = 10 # or this, up to you
change()
print li # returns [1, 2, 10]
次の場合:
def change(l):
l=[1,2,10]
実際には、どのリストがl
指すかを変更しています。に渡されるリスト インスタンスを変更する必要がありますchange
。あなたはappend
それをすることができます、あなたはそれpop
からすることができchange
ます.
def change(l):
l[:] = [1,2,10]