2012-01-05 2 views
2

내가 (C 코드) 할 노력했다 : 나는이 코드 조각으로 행동처럼 유사한 포인터를 할 파이썬을 기다리고 있었다목록에 추가 할 때 왜 파이썬이 포인터 대신 값을 복사합니까?

int a = 2, b = 3, c = 4; 

int* arr[3] = {&a, &b, &c}; 

for (int i = 0; i < 3; ++i) { 
    if (*(arr[i]) > 1) { 
     *(arr[i]) = 1 
    } 
} 

.

>>> a = 2 
>>> b = 3 
>>> c = 4 
>>> for x in [a, b, c]: 
...  if x > 1: 
...    x = 1 
... 
>>> a,b,c 
(2, 3, 4) 

어떻게 C 코드와 같은 동작을 파이썬에서 얻을 수 있습니까?

+0

아니요. 루프에서 "오류"가 발생합니다. 'x is a' ('b, c'에 대해서 등등)를 체크하면, 그것도 같은 대상이라는 것을 알 수 있습니다. – delnan

답변

2

을이 도움이 될

a,b,c = [ 1 if i>1 else i for i in [ a, b, c ] ] 
a,b,c = map(lambda x: 1 if x>1 else x, [a,b,c]) #lambda or name of some function 
+0

이 코드는'index'가리스트를 순차적으로 검색하기 때문에 O (n^2)의 복잡성을 가지며 다른 의미를가집니다 ('index'는 동일한 값의 객체가있는 첫 번째 인덱스를 반환합니다). – delnan

+0

좋아, 또 다른 해결책을 찾았습니다 :) – abuduba

+0

이것은 정확히 내가 성취하려는 것입니다. 이 솔루션을 가져 주셔서 감사합니다! 내가 할 수만 있다면 – juke

1

x = 5을 수행하면 기본 값이 아닌 참조가 변경됩니다. 이제 x 참조가 값 5를 가리키고 있습니다 (일반적으로 인터프리터에서 단 하나의 객체 임).

파이썬에서는 코드가 다르게 적용됩니다.

arr = [2, 3 , 4] 
def foo(x): 
    return x if x > 1 else x 
arr = [foo(a) for a in arr] 

을 심지어 한 라이너 수행 할 수 있습니다 : 당신은 무엇을 달성하려고하는 것은 다음과 같은 방식으로 이루어집니다 당신은 그것에 대해 변경 가능한 객체를 사용한다

>>> [1 if a > 1 else a for a in arr] 
[1, 1, 1] 
3

. 예를 들어
: 당신이 A, B, C가 필요한 경우

[1, 1, 1] 

가 :

a = 2 
b = 3 
c = 4 

ls = [a, b, c] 

for i, val in enumerate(ls): 
    if val > 1: 
     ls[i] = 1 

print ls 

당신을 제공 어쩌면

>>> [a, b, c] = ls 
>>> a 
1 
+0

가능한 경우 명시 적 루프가 아닌 목록 통합을 사용하십시오. – gruszczy

+1

맞습니다. 그러나이 경우 제 목표는 OP C와 파이썬 코드 구조에 가깝게 모방하는 것이 었습니다. – joaquin

6

파이썬 포인터가 없다. 그런 의미에서.

파이썬 변수는 메모리에있는 값이 아닌 값에 바인딩 된 이름이므로 한 변수의 값을 변경해도 동일한 값을 가진 다른 변수의 값은 변경되지 않습니다.

>>> a = 2 
>>> b = 3 
>>> c = 4 
>>> for x in 'a','b','c': 
... if locals()[x] > 1: 
...  locals()[x] = 1 
... 
>>> a 
1 

그러나, 내가 강력하게이 일에 대해 권하고 싶습니다 :

당신은 조금 당신이 using locals을 원하는 같은 것을 얻을 수 있습니다. 문제를 설명하는 또 다른 질문을 올리면 해결하려고 시도합니다. more "Pythonic" 방법이 있습니다.

은 그냥 dict에 값을 저장하는 경우가 있습니다

>>> vals = { 'a' : 2, 'b' : '3', 'c' : 4 } 
>>> for key,value in vals.items(): 
...  if value > 1: 
...  vals[key] = 1 
... 
>>> vals 
{'a': 1, 'c': 1, 'b': 1} 
+0

+10. 파이썬의 의미를 올바르게 가져 주셔서 감사합니다. 이 주제에 대해 너무 혼란 스러웠습니다 ... OP의 스 니펫이 예상대로 작동하지 않고 합리적인 대안을 제시하는 것이 상처를주지 않는 주요 이유를 확인했습니다. – delnan

1

나는 가정 당신은 실제로 오히려 일부 목록이 아니라, 일부 변수 세트를 검사하고 수정한다 뭘 하려는지 값. 그렇지 않다면 아마 여기에 나열된 다른 것들 중 하나, 즉 개별 변수 대신 실제 목록을 사용하고 싶을 것입니다. 나는 강력하게 이 아니지만은 대부분의 코드에서 이러한 종류의 기법을 권장하지만 특정 메타 프로그래밍 문제에 유용 할 수 있습니다.

그래서, 그와 함께 길에서, 당신은 바람에주의를 던져 이름으로 변수를 조작 할 수 있습니다 : 다른 답변으로

a, b, c = 2, 3, 4 

for name in ['a','b','c']: 
    if locals()[name] > 1: 
     locals()[name] = 1 

print a, b, c 
0

매우 기대가 할 수없는 이유로 설명하고있다

꽃다발에 추가 할 수있는 한 가지 해결책은 다음과 같습니다.

a,b,c = [1 if i > 1 else i for i in [a,b,c]] 
관련 문제