python: jak rozpoznać, czy zmienna jest tablicą czy skalarem

Mam funkcję, która pobiera argument NBins. Chcę wywołać tę funkcję skalarem 50 lub tablicą [0, 10, 20, 30]. Jak mogę zidentyfikować wewnątrz funkcji, jaka jest długość NBins? czy inaczej mówiąc, jeśli jest to Skalar czy wektor?

Próbowałem tego:

>>> 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()
>>> 

Jak widzisz, nie mogę zastosować len do P, ponieważ nie jest to tablica.... Czy jest coś w stylu isarray lub isscalar w Pythonie?

Dzięki

Author: otmezger, 2013-05-29

10 answers

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

Aby obsługiwać dowolny typ sekwencji, sprawdź collections.Sequence zamiast list.

Uwaga: isinstance obsługuje również krotkę klas, należy unikać sprawdzania type(x) in (..., ...) i jest niepotrzebne.

Możesz też sprawdzić not isinstance(x, (str, unicode))

 263
Author: jamylak,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-02-10 11:04:49

Poprzednie odpowiedzi zakładają, że tablica jest standardową listą Pythona. Jako ktoś, kto często używa numpy, polecam bardzo pythoniczny test:

if hasattr(N, "__len__")
 90
Author: jpaddison3,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-11-04 17:32:06

Łączenie odpowiedzi @jamylak i @jpaddison3 razem, jeśli chcesz być odporny na tablice numpy jako dane wejściowe i obsługiwać je w taki sam sposób, jak listy, powinieneś użyć

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

Jest to Odporne na podklasy tablic list, tuple i numpy.

I jeśli chcesz być odporny na wszystkie inne podklasy sekwencji (nie tylko list i tuple), użyj

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

Dlaczego powinieneś robić rzeczy w ten sposób z isinstance, a nie porównywać type(P) z wartością docelową? Oto przykład, gdzie tworzymy i badamy zachowanie NewList, trywialnej podklasy listy.

>>> 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

Pomimo porównań x i y jako równych, obsługa ich przez type spowodowałaby inne zachowanie. Jednakże, ponieważ x jest instancją podklasy list, użycie isinstance(x,list) daje pożądane zachowanie i traktuje x i y w ten sam sposób.

 28
Author: scottclowe,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-02-02 16:29:26

Czy istnieje odpowiednik iscalar () w numpy? Tak.

>>> np.isscalar(3.1)
True
>>> np.isscalar([3.1])
False
>>> np.isscalar(False)
True
 20
Author: jmhl,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-11-13 04:53:17

Podczas gdy podejście @ jamylak jest lepsze, oto podejście alternatywne

>>> N=[2,3,5]
>>> P = 5
>>> type(P) in (tuple, list)
False
>>> type(N) in (tuple, list)
True
 13
Author: Sukrit Kalra,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-05-29 06:37:21

Another alternative approach (use of class name property):

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

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

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

type(N).__name__ in ('list', 'tuple')
True
Nie trzeba niczego importować.
 3
Author: Marek,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-05-29 07:13:58

Po prostu użyj size zamiast 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
 3
Author: Mathieu Villion,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-12-04 09:56:40
>>> N=[2,3,5]
>>> P = 5
>>> type(P)==type(0)
True
>>> type([1,2])==type(N)
True
>>> type(P)==type([1,2])
False
 2
Author: simple_human,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-05-29 06:40:59

Można sprawdzić typ danych zmiennej.

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

To daje się umieścić jako typ danych P.

<type 'int'>

Tak, że można odróżnić, że jest to liczba całkowita lub tablica.

 2
Author: unnati patil,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-05-29 06:54:11

Dziwię się, że tak podstawowe pytanie nie wydaje się mieć natychmiastowej odpowiedzi w Pythonie. Wydaje mi się, że prawie wszystkie proponowane odpowiedzi używają pewnego rodzaju sprawdzanie, które zwykle nie jest zalecane w Pythonie i wydaje się ograniczone do konkretnego przypadku(zawodzą z różnymi typami liczbowymi lub ogólnymi obiektami iteracyjnymi, które nie są krotkami lub listami).

Dla mnie to, co działa lepiej, to importowanie numpy i używanie tablicy.rozmiar, na przykład:

>>> 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

Uwaga także:

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

Out[5]: 2

Ale:

>>> 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
 1
Author: Vincenzooo,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-08-29 16:35:52