3

だから私はPython 3.3でリストを扱っています.ここに私のコード例があります:

def change_to_z(lis):
    lis[3] = 'z'

def change_to_k(lis):
    lis[4] = 'k'


def split(lis):
    lis = lis[3:] + lis[:3]

totest = ['a', 'b', 'c', 'd', 'e', 'f']

change_to_z(totest)
print(totest)
change_to_k(totest)
print(totest)
split(totest)
print(totest)

そして出力:

['a', 'b', 'c', 'z', 'e', 'f']
['a', 'b', 'c', 'z', 'k', 'f']
['a', 'b', 'c', 'z', 'k', 'f']

最初の 2 つの関数を呼び出したときにリストを変更できたことに注目してください。一方、totest は、リストが変更されたとしても、常にリストを参照していました。

ただし、3 番目の関数では、変数 totest はリストの最新の変更バージョンを参照しなくなります。私のデバッガーは、関数「分割」内ではリストが反転されているが、関数の外では反転されていないことを教えてくれます。変数名がリストを参照しなくなったのはなぜですか?

なぜこれが起こるのですか?そして、これはどのオペレーターで起こりますか?変数名が関数で変更された後もリストを参照しているのに、他の演算子ではそのように動作しないことがあるのはなぜですか?

4

2 に答える 2

1

あなたは関数について間違ってscopeいます。

提供されたリストを本当に変更したい場合は、次の 2 つの方法のいずれかを試すことができます。

def split(lis):
    global lis
    lis = lis[3:] + lis[:3]

またはそれ以上

def split(lis):
    lis[:] = lis[3:] + lis[:3] # Credits go to drewk for pointing this out

しているとき

def split(lis):
    lis = lis[3:] + lis[:3]

このsplit関数では、提供されたリストと同じ識別子を持つローカル リストを作成しています。ただし、渡されたリストはglobalであるため、これら 2 つが衝突することはありません。

試して、それらが本当に違うかどうかを知りたい場合は、使用してくださいid()

lis = [1, 2, 3]
def split(lis):
    lis = lis[3:] + lis[:3]
    print id(lis)
split(lis)
print id(lis)

上記コードの出力

40785920
40785600

メモリの場所がどのように異なるかに注意してください

于 2013-11-05T04:47:12.033 に答える