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


283

인수를 취하는 함수가 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파이썬은?

감사


3
테스트를 해 보셨습니까 type?
Sukrit Kalra

답변:


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

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

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

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


3
고마워, 나는 list스칼라에 대해
거꾸로 뒤집는

3
이것은 훌륭한 답변이지만 collections.Sequence문자열의 ABC이기도하므로 고려해야합니다. 와 같은 것을 사용하고 if type(x) is not str and isinstance(x, collections.Sequence):있습니다. 이것은 좋지 않지만 신뢰할 수 있습니다.
bbenne10

2
@ bbenne10 확실하지만 피하고 파이썬 2 type도 확인하십시오not isinstance(x, (str, unicode))
jamylak

왜 "(..., ...)에서 type (x)를 피해야하며 불필요합니다"라고 말했습니까? 당신이 그렇게 말하면, 왜 그런지 설명하는 것은 매우 친절 할 것입니다. 어쩌면 내가 왜 피해야하는지 궁금해하는 사람은 아닙니다.
Olivier Pons


119

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

if hasattr(N, "__len__")

12
문자열에는 __len__속성이 있습니다 (기술적으로 스칼라 유형이 아니라고 생각합니다)
xofer

20
if hasattr(N, '__len__') and (not isinstance(N, str))문자열을 올바르게 설명합니다.
Thucydides411411.

1
또한 Python 3에 대한 dict에 대한 설명
Bruno Henrique

44

@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동일하게한다.


이것이 내 요구에 가장 적합한 대답입니다. 방금 세트도 추가했습니다. 나는 dicts에 대해 강력하고 싶지 않기 때문입니다. isinstance(P, (list, tuple, set, np.ndarray))
산티아고

32

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

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

6
더 좋으며 예를 들면 다음과 같습니다. >>> np.isscalar('abcd')returns True.
Syrtis Major Major

감사! 이것은 위의 것보다 훨씬 일반적인 예이므로 선호해야합니다. 또한 OP의 질문에 대한 직접적인 답변입니다.
Cristóbal Sifón 2016 년

1
좋은. 하나의 문제는 isscalar (None)이 False를 반환한다는 것입니다. Numpy는 이것을 다음과 같이 구현합니다return (isinstance(num, generic) or type(num) in ScalarType or isinstance(num, numbers.Number))
Shital Shah

5
안타깝게도 numpy.isscalar()기능은 많은 양립 할 수없는 디자인 결함을 겪고 있으며 향후 개정시에는 더 이상 사용되지 않을 것입니다 . 공식 문서 를 바꾸려면 : "거의 모든 경우 0d 배열에 대해 true를 올바르게 반환 np.ndim(x) == 0하므로 거의 모든 경우에 대신 사용해야 np.isscaler(x)합니다." 따라서 포워드를 대체 할 numpy.isscalar()수 있는 강력한 포워드 호환 대안 은 numpy.ndim()다음과 같습니다. 예 :def is_scalar(obj): return np.ndim(obj) == 0
Cecil Curry

실제로 이것은 np.isscalar혼란 스럽기 때문에 upvoted해서는 안됩니다 . 공식 문서는 np.array.ndim어디서나 사용을 제안했습니다 . 즉, np.isscalar(np.array(12))False이지만 np.array(12).ndim0 이므로 스칼라로 간주해야 합니다.
knh190

17

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

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

2
답을 내려 놓은 사람도 이유를 제시한다면 좋을 것입니다.
Sukrit Kalra

실제로 upvoted했지만 2.7에서 작동하지 않는 것을 깨달았습니다 , <모듈>의 1 행
Oleg Gryb 2018 년

@OlegGryb : 사용해보십시오 type(p) in (list, ).
Sukrit Kalra

아, 그것은 목록이 아닌 오른쪽에있는 튜플입니다. 감사합니다. 지금 작동합니다. 유감스럽게도, 2 배까지
찬성

3

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

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

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

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

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

가져올 필요가 없습니다.


3

내가 찾은 가장 좋은 방법은 다음과 같습니다 . __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

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


2
>>> N=[2,3,5]
>>> P = 5
>>> type(P)==type(0)
True
>>> type([1,2])==type(N)
True
>>> type(P)==type([1,2])
False

2

변수의 데이터 타입을 확인할 수 있습니다.

N = [2,3,5]
P = 5
type(P)

P의 데이터 유형으로 표시합니다.

<type 'int'>

정수 또는 배열임을 구별 할 수 있습니다.


2

그러한 기본적인 질문이 파이썬에서 즉각적인 대답을하지 않는 것으로 놀랐습니다. 거의 모든 제안 된 답변은 일종의 유형 검사를 사용하는 것으로 보입니다.

나를 위해 더 잘 작동하는 것은 numpy를 가져오고 array.size를 사용하는 것입니다.

>>> a=1
>>> np.array(a)
Out[1]: array(1)

>>> np.array(a).size
Out[2]: 1

>>> np.array([1,2]).size
Out[3]: 2

>>> np.array('125')
Out[4]: 1

참고 사항 :

>>> len(np.array([1,2]))

Out[5]: 2

그러나:

>>> len(np.array(a))
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-40-f5055b93f729> in <module>()
----> 1 len(np.array(a))

TypeError: len() of unsized object

또한 그들 중 어느 것도 발전기를 다루지 않는 것 같습니다.
RhysC

2

size대신에 간단하게 사용하십시오 len!

>>> from numpy import size
>>> N = [2, 3, 5]
>>> size(N)
3
>>> N = array([2, 3, 5])
>>> size(N)
3
>>> P = 5
>>> size(P)
1

2
나가서 설명하자면 NameError : 이름 '크기'정의되지 않은

1
사실입니다. 나는 그것을 알지 못하고 numpy 크기를 사용하고있었습니다. 당신이 필요로하는 : numpy 가져 오기 크기에서
Mathieu Villion

2
np.size(5)그리고 np.size([5])둘 다 == 1이므로 이것이 유형을 올바르게 구별하지 못합니다 (즉, 스칼라 식별). 이것이 목표라고 생각합니다.
마이클

이것은 흥미로운 발언입니다. 원래 질문은 Matlab 함수 인 isscalar를 나타냅니다. Matlab에서는 스칼라와 크기가 1 인 배열간에 차이가 전혀 없으며 벡터 또는 N 차원 배열 일 수 있습니다. IMHO, 이것은 Matlab의 플러스입니다.
Mathieu Villion

0

preds_test [0]의 형태는 (128,128,1) isinstance () 함수를 사용하여 데이터 유형을 검사 할 수 있습니다. isinstance는 2 개의 인수를 사용합니다. 첫 번째 인수는 데이터입니다. 두 번째 인수는 데이터 유형입니다. isinstance (preds_test [0], np.ndarray)는 출력을 True로 제공합니다. preds_test [0]이 배열임을 의미합니다.


0

제목의 질문에 답하기 위해 변수가 스칼라인지 확인하는 직접적인 방법은 변수를 부동 소수점으로 변환하는 것입니다. 당신이 얻는다면 그렇지 TypeError않습니다.

N = [1, 2, 3]
try:
    float(N)
except TypeError:
    print('it is not a scalar')
else:
    print('it is a scalar')
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.