2017-05-20 10 views
2

私はこのコードスニペットでは、0とR-1(両端を含む)の間であることが保証されている数値のリストを並べ替えています。次のコードはソートを正しく実行しますが、渡された入力が変更されないまま残っている理由はわかりません。機能の後にそのままこの例ではinpなぜリストはPythonの参照混乱によって渡されます

def bucket(arr, R): 
    assert type(arr) is list 
    for i in arr: 
     assert i >=0 and i < R 
    b = [0] * R 
    for i in arr: 
     b[i]+=1 
    arr = [] 
    for ind, v in enumerate(b): 
     arr = arr + [ind] * v 
    print(arr) 

が呼び出されました:

>>> inp 
[3, 1, 4, 5, 4, 5, 5, 5, 1, 5] 
>>> bucket(inp, 8) 
[1, 1, 3, 4, 4, 5, 5, 5, 5, 5] 
>>> inp # unchanged, why? 
[3, 1, 4, 5, 4, 5, 5, 5, 1, 5] 
+1

*参照の意味で渡す*はPython *ではサポートされていません。 –

+1

これを読む:https://nedbatchelder.com/text/names.html –

答えて

2

を使用することができます。同様に、 -loop内に新しいリストを作成し、arr = arr + [ind] * v操作で作成します。あなたは単にそれを変更することができ

def bucket(arr, R): 
    assert type(arr) is list 
    for i in arr: 
     assert i >= 0 and i < R 
    b = [0] * R 
    for i in arr: 
     b[i] += 1 
    arr[:] = [] # remove all items from the list (in-place) 
    for ind, v in enumerate(b): 
     arr.extend([ind] * v) # extend the list in-place, you could also use "arr += [ind] * v" 
    print(arr) 

例:

>>> inp = [3, 1, 4, 5, 4, 5, 5, 5, 1, 5] 
>>> bucket(inp, 8) 
[1, 1, 3, 4, 4, 5, 5, 5, 5, 5] 
>>> inp 
[1, 1, 3, 4, 4, 5, 5, 5, 5, 5] 
1

既存の配列への参照を失って、新しいものを作成している[]arrに割り当てること。あなたは、新しいリストを操作する上でラインarr = []にし、この時点からarrと呼ばれる新しい変数を作成するので、それを変更するには

、あなたは

inp.sort() 

More info on sort vs sorted

0

Pythonは代入によって渡され、セマンティクスが値でJavaのパスに非常に似ています。

ポインタを値渡ししているため、混乱が生じます。

x = 3 
def change_x(x): 
    x = 5 
    return x 
change_x(x) 
print x 
# Outputs 3 

xの値を外:これは、関数の内部ポインタを変更することはできませんが、誰が、ポインタが(すなわちデータ)を指しているので、例えばされているものの変更からあなたを止めることはできません意味しますxが関数に入る前に関数(この場合は3)がコピーされたので、代入は何もしません。これは通例、値渡しを聞いたときに期待されるものです。

x = [1,2,3] 
print(id(x)) 
# Outputs some "address" 
def change_x(x): 
    x.clear() 
    x.extend([4,5,6]) 
    print(id(x)) 
    # Outputs the SAME address as above 
    return x 
change_x(x) 
print(x) 
# Outputs [4,5,6] 

何がいいですか。私はちょうどxを変更できないと言ったと思った。キャッチは私たちがxを変えなかったことです!私たちはちょうどxが指しているデータを変更しました(ここでは微妙ですが、重要な違いがあります)。 xはまだ同じポインタです。 idによって出力されるアドレスは同じです。

x = [1,2,3] 
print(id(x)) 
# Outputs some "address" 
def change_x(x): 
    x = [4,5,6] 
    print(id(x)) 
    # Outputs some DIFFERENT "address". The pointer to x was changed (inside this function). 
    return x 
change_x(x) 
print(x) 
# Outputs [1,2,3] 

xが渡される前に(データではなくポインタ値がコピーされた)xの値がコピーされました。だから、再割り当ては何もしません。今回はid関数がの値がと異なることに注意してください。したがって、関数が返った後、xの元の値(ポインタの元の値)が得られます。

関連する問題