[python] 파이썬 : 변수가 배열인지 또는 스칼라인지 식별하는 방법

인수를 취하는 함수가 NBins있습니다. 스칼라 50또는 배열 을 사용 하여이 함수를 호출하고 싶습니다 [0, 10, 20, 30]. 함수 내에서 길이를 어떻게 식별 할 수 NBins있습니까? 또는 스칼라 또는 벡터라면 다르게 말했습니까?

나는 이것을 시도했다 :

>>> N=[2,3,5]
>>> P = 5
>>> len(N)
3
>>> len(P)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: object of type 'int' has no len()
>>> 

보시다시피, 내가 적용 할 수 없습니다 lenP가 배열이 아닌 이후, …. 같은 뭔가가 isarrayisscalar파이썬은?

감사



답변

>>> isinstance([0, 10, 20, 30], list)
True
>>> isinstance(50, list)
False

모든 유형의 시퀀스를 지원하려면 collections.Sequence대신 확인하십시오 list.

참고 : isinstance클래스 튜플도 지원하므로 검사 type(x) in (..., ...)를 피해야하며 불필요합니다.

확인하고 싶을 수도 있습니다 not isinstance(x, (str, unicode))


답변

이전 답변은 배열이 파이썬 표준 목록이라고 가정합니다. numpy를 자주 사용하는 사람은 다음과 같은 pythonic 테스트를 권장합니다.

if hasattr(N, "__len__")


답변

@jamylak과 @ jpaddison3의 답변을 결합하여 입력과 같은 numpy 배열에 견고하고 목록과 동일한 방식으로 처리 해야하는 경우 사용해야합니다

import numpy as np
isinstance(P, (list, tuple, np.ndarray))

이것은리스트, 튜플 및 numpy 배열의 서브 클래스에 대해 강력합니다.

그리고리스트와 튜플뿐만 아니라 시퀀스의 다른 모든 서브 클래스에도 견고하게하려면

import collections
import numpy as np
isinstance(P, (collections.Sequence, np.ndarray))

목표 값과 isinstance비교하지 말고 왜 이런 식으로 일을해야 type(P)합니까? 다음은 NewList간단한 하위 클래스 인의 동작을 만들고 연구하는 예 입니다.

>>> class NewList(list):
...     isThisAList = '???'
...
>>> x = NewList([0,1])
>>> y = list([0,1])
>>> print x
[0, 1]
>>> print y
[0, 1]
>>> x==y
True
>>> type(x)
<class '__main__.NewList'>
>>> type(x) is list
False
>>> type(y) is list
True
>>> type(x).__name__
'NewList'
>>> isinstance(x, list)
True

에도 불구 x하고 y별로 처리, 동일로 비교 type다른 동작이 발생할 것입니다. 그러나, 이후에는 x서브 클래스의 인스턴스 인 list사용, isinstance(x,list)원하는 동작 및 취급 부여합니다 xy동일하게한다.


답변

numpy에 isscalar ()와 동등한 것이 있습니까? 예.

>>> np.isscalar(3.1)
True
>>> np.isscalar([3.1])
False
>>> np.isscalar(False)
True


답변

@jamylak의 접근법이 더 낫지 만 여기에 다른 접근법이 있습니다.

>>> N=[2,3,5]
>>> P = 5
>>> type(P) in (tuple, list)
False
>>> type(N) in (tuple, list)
True


답변

다른 대체 방법 (클래스 이름 속성 사용) :

N = [2,3,5]
P = 5

type(N).__name__ == 'list'
True

type(P).__name__ == 'int'
True

type(N).__name__ in ('list', 'tuple')
True

가져올 필요가 없습니다.


답변

내가 찾은 가장 좋은 방법은 다음과 같습니다 . __len__및의 존재를 확인하십시오 __getitem__.

왜 그런지 물어봐도 될까요? 그 이유는 다음과 같습니다.

  1. isinstance(obj, abc.Sequence)PyTorch의 Tensor를 포함하여 일부 객체에서 인기있는 메소드 는 구현하지 않기 때문에 실패합니다 __contains__.
  2. 불행하게도, 파이썬의 collections.abc 아무것도 단지를 검사하는 것이 없다 __len__하고 __getitem__있는 내가 느끼는 객체 배열 등을위한 최소한의 방법이 있습니다.
  3. 그것은 목록, 튜플, ndarray, 텐서 등에서 작동합니다.

따라서 더 이상 고민하지 않고 :

def is_array_like(obj, string_is_array=False, tuple_is_array=True):
    result = hasattr(obj, "__len__") and hasattr(obj, '__getitem__')
    if result and not string_is_array and isinstance(obj, (str, abc.ByteString)):
        result = False
    if result and not tuple_is_array and isinstance(obj, tuple):
        result = False
    return result

대부분의 경우 문자열이 배열이 아닌 값으로 간주되기 때문에 기본 매개 변수를 추가했습니다. 튜플도 마찬가지입니다.