파이썬은 Ruby에서 || =와 같은 "또는 같음"함수를 가지고 있습니까?


82

그렇지 않은 경우이를 수행하는 가장 좋은 방법은 무엇입니까?

지금 나는 (django 프로젝트를 위해)하고있다.

if not 'thing_for_purpose' in request.session:
    request.session['thing_for_purpose'] = 5

하지만 꽤 어색합니다. Ruby에서는 다음과 같습니다.

request.session['thing_for_purpose'] ||= 5

훨씬 좋습니다.


23
이 두 코드는 실제로 매우 다릅니다. Python 버전은 dict에 전혀 없으면 5로 설정하고, Ruby 버전은 false 값으로 설정되어 있으면 5로 설정합니다.
Glenn Maynard

2
@Glenn, 그다지 다르지는 않지만 아주 다릅니다. 초기화되지 않은 해시 값이 반환되기 때문에 nil(부울 컨텍스트에서 false)이 관용구는 sean이 사용한 목적에 정확히 사용되는 경우가 많습니다. 관용구에만 작동하지만, 경우 물론, nilfalse(관용구가 미세하므로 매우 자주 사실이다) 해시에없는 정당한 값은
horseyguy

8
@banister : "very"와 "quite"사이에 선을 그릴 수있는 곳은 모르겠지만 요점은 이것들이 동등한 진술이 아니라는 점이며 차이점을 이해하는 것이 중요합니다. (False는 종종 해시에서 유효한 값입니다. 부울 필드의 기본값을 true로 설정하고 싶을 때 물릴 것입니다. 이는 Ruby 관용구의 중요한 단점입니다.)
Glenn Maynard

예 파이썬 예제에 더 가깝다 정의 또는 처럼, //=어떤 당신이 찾을 . 나는 ||=또한 Perl에서 유래 했다고 생각합니다 .
draegtun

아 좋은 점, 모두. 나는이 차이를 알아 차리지 못했다.
Sean W.

답변:


186

받아 들여지는 대답은 dicts에 좋지만 제목은 Ruby의 || = 연산자에 해당하는 일반적인 것을 찾습니다. 파이썬에서 || =와 같은 일을하는 일반적인 방법은 다음과 같습니다.

x = x or new_value

36
이 답변은 Google 검색에서 여기에 오는 사람들이 찾고있는 것 같습니다.
gradi3nt 2014 년

이것은 정말 최고의 대답입니다.
AdamC

6
Ruby와 달리이 코드는 x이전에 정의 된 경우에만 작동합니다 (예 None: 클래스 초기화 메서드에서로 설정 됨 ).
oli

3
사실, 이것은 Ruby의 || =와 똑같이 작동하지 않습니다. 주의해야 할 또 다른 것은 x의 '진실성'입니다. X == 0 0이 false로 간주되기 때문에 파이썬에서, 당신은 NEW_VALUE거야,하지만 루비는 0거야 경우
조셉 Sheedy

1
|| =만큼 효율적입니까? || =는 null이 아니면 할당을하지 않지만 항상 할당을합니다. 파이썬 컴파일러가 생각보다 영리합니까?
jsarma

17

dict있습니다 setdefault().

그래서 만약 것은 request.sessionA는 dict:

request.session.setdefault('thing_for_purpose', 5)

모호하게 비슷하지만 Ruby의 || =와는 전혀 다릅니다.
AdamC

1
키가 이미 설정되어 있어도 기본 표현식이 평가된다는 점에서 크게 다릅니다. 기본값을 평가하거나 키에 두 번 이상 또는 둘 다 액세스하지 않고는 원래 질문을 해결할 방법이 없습니다.
slinkp

10

미들웨어 등에서 수행하는 경우 기본값을 설정하는 것이 합리적이지만 한 요청의 컨텍스트에서 기본값이 필요한 경우 :

request.session.get('thing_for_purpose', 5) # gets a default

보너스 : 여기에 실제로 ||=파이썬으로 하는 방법이 있습니다.

def test_function(self, d=None):
    'a simple test function'
    d = d or {}

    # ... do things with d and return ...

10

정확한 답 : 아닙니다 파이썬은 하나가없는 내장 연산자 op번역 할 수 있습니다 x = x or yx op y.

그러나 거의 그렇습니다. 비트 또는 같음 연산자 ( |=) 두 피연산자가 모두 부울로 처리되는 경우 위에서 설명한대로 작동합니다. (주의 사항은 무엇입니까? 대답은 물론 아래에 있습니다.)

첫째, 기능의 기본 데모 :

x = True
x    
Out[141]: True

x |= True
x    
Out[142]: True

x |= False
x    
Out[143]: True

x &= False
x    
Out[144]: False

x &= True
x    
Out[145]: False

x |= False
x    
Out[146]: False

x |= True
x   
Out[147]: True

주의 할 점은 파이썬이 엄격하게 유형화되지 않았기 때문에 값이 표현식에서 부울로 취급 되더라도 비트 연산자에 주어지면 단락되지 않습니다. 예를 들어 목록을 지우고 True삭제 된 요소 가있는 경우 반환하는 부울 함수가 있다고 가정합니다 .

def  my_clear_list(lst):
    if not lst:
        return False
    else:
        del lst[:]
        return True

이제 단락 동작을 다음과 같이 볼 수 있습니다.

x = True
lst = [1, 2, 3]
x = x or my_clear_list(lst)
print(x, lst)

Output: True [1, 2, 3]

그러나를 or비트 단위 또는 ( |)로 전환하면 단락이 제거되므로 함수가 my_clear_list실행됩니다.

x = True
lst = [1, 2, 3]
x = x | my_clear_list(lst)
print(x, lst)

Output: True []

위의 x = x | my_clear_list(lst)x |= my_clear_list(lst).


당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.