2017-02-07 2 views
-1

그래서 목록 목록의 특정 목록 요소를 오른쪽으로 이동시키는 코드를 작성하고 있습니다.함수 호출 중 매개 변수 업데이트

def right(state,index): 
    r_state=state 
    new_state = [] 
    for j in range(1,len(r_state[index])): 
     new_state.append(r_state[index][j-1]) 
    new_state.insert(0, r_state[index][-1]) 
    r_state[index]=new_state 
    return r_state 

#case1 
for i in range(2): 
    print(right([[1,2,3,4],[5,6,7,8],[9,10,11,12],[13,14,15,16]], i)) 

#case2 
def printer(node): 
    for i in range(2): 
     print(right(node, i)) 

printer([[1,2,3,4],[5,6,7,8],[9,10,11,12],[13,14,15,16]]) 

경우 (1)가 나에게 내가 원하는 출력을 제공합니다 (인덱스에 해당하는 하나 개의 하위 목록 변경) :

[[4, 1, 2, 3], [5, 6, 7, 8], [9, 10, 11, 12], [13, 14, 15, 16]] 
[[1, 2, 3, 4], [8, 5, 6, 7], [9, 10, 11, 12], [13, 14, 15, 16]] 

그러나 케이스 (2) 목록 내 목록을 업데이트 끝

[[4, 1, 2, 3], [5, 6, 7, 8], [9, 10, 11, 12], [13, 14, 15, 16]] 
[[4, 1, 2, 3], [8, 5, 6, 7], [9, 10, 11, 12], [13, 14, 15, 16]] 

목록이 업데이트되는 이유는 무엇입니까? 또한 케이스 1과 동일한 출력을 얻기 위해 케이스 2를 어떻게 수정할 수 있습니까?

+2

명시 적으로 목록에 돌연변이를하기 때문에 함수에 전달합니다. 'r_state = state' *는 복사본을 만들지 않습니다. 할당은 결코 파이썬에서 사본을 만들지 않습니다 * –

+1

또한,'printer' 함수는 이미'print'를 사용하고 있습니다. 그래서 함수를 호출 한 결과를'print'하면 함수는 아무 것도 돌려주지 않기 때문에'None'이됩니다. –

+1

왜'r_state = state'를 사용합니까? – roganjosh

답변

1

문제는 할당이 파이썬에서 복사본을 만들지 않는다는 것입니다. 명시 적으로 복사해야합니다. 자신의 코드에서 목록을 복사,

r_state = state 

또한

r_state = state[:] 

하려면 r_state = list(state)뿐만 아니라 사용 볼 수 변경합니다. 파이썬 3은 훨씬 더 명시 적입니다 :

r_state = state.copy() 

또한 목록 이해를 사용하여 새 목록을 만들 수 있습니다. 다음은 시퀀스의 요소를 이동하는 모듈러 산술을 사용하여 빠른 - 및 - 더러운 방법입니다 : 마지막으로 이해 아마도 조금 너무 조밀

>>> def shift_right(lst, shift): 
...  modulus = len(lst) 
...  return [lst[(i + shift)%modulus] for i in range(len(lst))] 
... 
>>> def right(state, index): 
...  return [shift_right(sub, 1) if i == index else sub for i, sub in enumerate(state)] 
... 
>>> test = [[1,2,3,4],[5,6,7,8],[9,10,11,12],[13,14,15,16]] 
>>> shift_right(test[0], 1) 
[2, 3, 4, 1] 
>>> shift_right(test[0], 2) 
[3, 4, 1, 2] 
>>> shift_right(test[0], 3) 
[4, 1, 2, 3] 
>>> shift_right(test[0], 4) 
[1, 2, 3, 4] 
>>> shift_right(test[0], 5) 
[2, 3, 4, 1] 
>>> right(test, 0) 
[[2, 3, 4, 1], [5, 6, 7, 8], [9, 10, 11, 12], [13, 14, 15, 16]] 
>>> right(test, 1) 
[[1, 2, 3, 4], [6, 7, 8, 5], [9, 10, 11, 12], [13, 14, 15, 16]] 

것을, 대신 다음과 같이 작성할 수 있습니다 :

>>> def right(state, index): 
...  result = [] 
...  for i, sub in enumerate(state): 
...   if i == index: 
...    result.append(shift_right(sub, 1)) 
...   else: 
...    result.append(sub) 
...  return result 
... 
>>> right(test, 0) 
[[2, 3, 4, 1], [5, 6, 7, 8], [9, 10, 11, 12], [13, 14, 15, 16]] 
>>> right(test, 1) 
[[1, 2, 3, 4], [6, 7, 8, 5], [9, 10, 11, 12], [13, 14, 15, 16]] 
>>> right(test, 2) 
[[1, 2, 3, 4], [5, 6, 7, 8], [10, 11, 12, 9], [13, 14, 15, 16]] 
>>> right(test, 3) 
[[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12], [14, 15, 16, 13]] 
>>> 
+0

오늘 새로운 것을 배웠습니다. 감사합니다. – AdR

관련 문제