Programing

왜리스트에 사전과 같은 안전한 "get"메소드가 없는가?

lottogame 2020. 4. 17. 08:11
반응형

왜리스트에 사전과 같은 안전한 "get"메소드가 없는가?


왜리스트에 사전과 같은 안전한 "get"메소드가 없는가?

>>> d = {'a':'b'}
>>> d['a']
'b'
>>> d['c']
KeyError: 'c'
>>> d.get('c', 'fail')
'fail'

>>> l = [1]
>>> l[10]
IndexError: list index out of range

궁극적으로 .geta dict는 예외가 발생하지 않고 키가 있는지 확인하고 값을 반환하는 것이 비효율적 인 연관 컬렉션 (값과 이름이 연관되어 있기 때문에) 안전한 방법 이 없을 것입니다. len메소드가 매우 빠르기 때문에 목록 요소에 액세스하는 예외를 피하기 위해 . .get방법을 사용하면 사전에서 37 번째 항목에 직접 액세스하지 않고 이름과 연관된 값을 쿼리 할 수 ​​있습니다 (목록에서 요구하는 것과 더 유사 함).

물론 이것을 직접 구현할 수 있습니다.

def safe_list_get (l, idx, default):
  try:
    return l[idx]
  except IndexError:
    return default

__builtins__.list생성자에 monkeypatch 할 수도 __main__있지만 대부분의 코드에서 사용하지 않기 때문에 덜 널리 퍼질 것입니다. 이 코드를 자신의 코드로 만든 목록과 함께 사용하려면 하위 클래스를 작성 list하고 get메소드를 추가하면 됩니다.


첫 번째 요소를 원하면 작동합니다. my_list.get(0)

>>> my_list = [1,2,3]
>>> next(iter(my_list), 'fail')
1
>>> my_list = []
>>> next(iter(my_list), 'fail')
'fail'

나는 그것이 당신이 요구 한 것이 아니라 다른 사람들을 도울 수 있다는 것을 알고 있습니다.


.get을 사용하는 대신 목록을 사용하는 것이 좋습니다. 사용법 차이입니다.

>>> l = [1]
>>> l[10] if 10 < len(l) else 'fail'
'fail'

아마도 목록 의미에 대해서는별로 의미가 없기 때문일 것입니다. 그러나 서브 클래 싱을 통해 쉽게 자신 만의 것을 만들 수 있습니다.

class safelist(list):
    def get(self, index, default=None):
        try:
            return self.__getitem__(index)
        except IndexError:
            return default

def _test():
    l = safelist(range(10))
    print l.get(20, "oops")

if __name__ == "__main__":
    _test()

이 시도:

>>> i = 3
>>> a = [1, 2, 3, 4]
>>> next(iter(a[i:]), 'fail')
4
>>> next(iter(a[i + 1:]), 'fail')
'fail'

가장 좋은 방법은 목록을 dict로 변환 한 다음 get 메소드로 액세스하는 것입니다.

>>> my_list = ['a', 'b', 'c', 'd', 'e']
>>> my_dict = dict(enumerate(my_list))
>>> print my_dict
{0: 'a', 1: 'b', 2: 'c', 3: 'd', 4: 'e'}
>>> my_dict.get(2)
'c'
>>> my_dict.get(10, 'N/A')

jose.angel.jimenez의 크레딧


"oneliner"팬들을 위해…


목록의 첫 번째 요소를 원하거나 목록이 비어있는 경우 기본값을 원하면 다음을 시도하십시오.

liste = ['a', 'b', 'c']
value = (liste[0:1] or ('default',))[0]
print(value)

보고 a

liste = []
value = (liste[0:1] or ('default',))[0]
print(value)

보고 default


다른 요소의 예…

liste = ['a', 'b', 'c']
print(liste[0:1])  # returns ['a']
print(liste[1:2])  # returns ['b']
print(liste[2:3])  # returns ['c']

기본 폴백으로…

liste = ['a', 'b', 'c']
print((liste[0:1] or ('default',))[0])  # returns a
print((liste[1:2] or ('default',))[0])  # returns b
print((liste[2:3] or ('default',))[0])  # returns c

테스트 Python 3.6.0 (v3.6.0:41df79263a11, Dec 22 2016, 17:23:13)


그래서 나는 이것에 대해 더 많은 연구를했으며 이것에 대해 특별한 것이 없다는 것이 밝혀졌습니다. list.index (value)를 찾았을 때 흥분되어 지정된 항목의 색인을 반환하지만 특정 색인에서 값을 얻는 데는 아무것도 없습니다. 따라서 safe_list_get 솔루션을 사용하고 싶지 않다면 꽤 좋습니다. 시나리오에 따라 작업을 수행 할 수있는 1 개의 라이너 if 문이 있습니다.

>>> x = [1, 2, 3]
>>> el = x[4] if len(x) == 4 else 'No'
>>> el
'No'

'아니오'대신 '없음'을 사용할 수도 있습니다.

>>> x = [1, 2, 3]
>>> i = 2
>>> el_i = x[i] if len(x) == i+1 else None

또한 목록에서 첫 번째 또는 마지막 항목을 가져 오려면 작동합니다.

end_el = x[-1] if x else None

이것들을 함수로 만들 수도 있지만 여전히 IndexError 예외 솔루션을 좋아했습니다. 나는 safe_list_get솔루션 의 불완전한 버전을 실험 하여 조금 더 간단하게 만들었습니다 (기본값 없음).

def list_get(l, i):
    try:
        return l[i]
    except IndexError:
        return None

가장 빠른 것을 확인하기 위해 벤치마킹하지 않았습니다.


사전은 조회 용입니다. 출품작의 존재 여부를 묻는 것이 합리적입니다. 리스트는 일반적으로 반복됩니다. L [10]이 있는지 묻는 것이 아니라 L의 길이가 11인지 묻는 것이 일반적입니다.


유스 케이스는 기본적으로 고정 길이의 배열과 행렬을 수행 할 때만 관련이 있기 때문에 사전에 얼마나 오래 있는지 알 수 있습니다. 이 경우 일반적으로 None 또는 0으로 채우기 전에 실제로 작성하므로 실제로 사용할 인덱스가 이미 존재합니다.

당신은 이것을 말할 수 있습니다 : 사전에 .get ()이 꽤 자주 필요합니다. 풀 타임 프로그래머로 10 년을 보낸 후에 나는 목록에 필요하다고 생각하지 않습니다. :)

참고 URL : https://stackoverflow.com/questions/5125619/why-doesnt-list-have-safe-get-method-like-dictionary

반응형