Mam funkcję, która przyjmuje argument NBins
. Chcę zadzwonić do tej funkcji za pomocą skalara50
lub tablicy [0, 10, 20, 30]
. Jak mogę określić w ramach funkcji, jaka jest długość NBins
? lub powiedział inaczej, jeśli jest to skalar lub 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 widać, nie mogą ubiegać len
się P
, ponieważ nie jest tablicą .... Czy istnieje coś takiego jakisarray
lub isscalar
w Pythonie?
dzięki
type
?Odpowiedzi:
Aby obsłużyć dowolny typ sekwencji, zaznacz
collections.Sequence
zamiastlist
.Uwaga :
isinstance
obsługuje również krotkę klas,type(x) in (..., ...)
należy unikać sprawdzania i nie jest konieczne.Możesz także chcieć sprawdzić
not isinstance(x, (str, unicode))
źródło
list
by uzyskać fałsz dla skalarów ... dziękicollections.Sequence
jest to również ABC dla ciągu znaków, więc należy to wziąć pod uwagę. Używam czegoś takiegoif type(x) is not str and isinstance(x, collections.Sequence):
. To nie jest świetne, ale jest niezawodne.type
, a także sprawdźnot isinstance(x, (str, unicode))
Python 2Poprzednie odpowiedzi zakładają, że tablica jest standardową listą Pythona. Jako ktoś, kto często używa numpy, polecam bardzo pythonowy test:
źródło
__len__
atrybut (tak sądzę, technicznie nie jest to typ skalarny)if hasattr(N, '__len__') and (not isinstance(N, str))
poprawnie uwzględniłoby łańcuchy.Łącząc 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ć
Jest to odporne na podklasy tablic list, krotek i tablic numpy.
A jeśli chcesz być odporny na wszystkie inne podklasy sekwencji (nie tylko listę i krotkę), użyj
Dlaczego warto robić to w ten sposób,
isinstance
a nie porównywaćtype(P)
z wartością docelową? Oto przykład, w którym tworzymy i badamy zachowanieNewList
trywialnej podklasy listy.Pomimo
x
iy
porównywanie jako równe, obchodzenie się z nimitype
spowodowałoby inne zachowanie. Jednakże, ponieważx
jest to przykład podklasylist
, stosującisinstance(x,list)
daje pożądane zachowanie i traktujex
iy
w ten sam sposób.źródło
isinstance(P, (list, tuple, set, np.ndarray))
Czy istnieje odpowiednik isscalar () w numpy? Tak.
źródło
>>> np.isscalar('abcd')
zwracaTrue
.return (isinstance(num, generic) or type(num) in ScalarType or isinstance(num, numbers.Number))
numpy.isscalar()
funkcja cierpi na szereg niemożliwych do pogodzenia wad projektowych i prawdopodobnie będzie przestarzała w przyszłości. Parafrazując oficjalną dokumentację : „W prawie wszystkich przypadkachnp.ndim(x) == 0
należy użyć zamiastnp.isscaler(x)
, ponieważ pierwsza zwróci również prawdę dla tablic 0d”.numpy.isscalar()
Zatem solidną, kompatybilną z przodu alternatywą byłoby trywialne zawijanienumpy.ndim()
: np.def is_scalar(obj): return np.ndim(obj) == 0
np.isscalar
jest mylące. Oficjalny dokument sugeruje używanienp.array.ndim
wszędzie, tzn.np.isscalar(np.array(12))
Jest fałszywy, podczas gdy powinien być uważany za skalarny, ponieważnp.array(12).ndim
wynosi 0.Chociaż podejście @ jamylak jest lepsze, tutaj jest podejście alternatywne
źródło
type(p) in (list, )
.Inne alternatywne podejście (użycie właściwości nazwy klasy ):
Nie musisz niczego importować.
źródło
Oto najlepsze podejście, jakie znalazłem: Sprawdź istnienie
__len__
i__getitem__
.Możesz zapytać dlaczego? Przyczyny obejmują:
isinstance(obj, abc.Sequence)
zawodzi w przypadku niektórych obiektów, w tym Tensora PyTorcha, ponieważ nie są one implementowane__contains__
.__len__
i__getitem__
które są minimalnymi metodami dla obiektów podobnych do tablicy.Więc bez zbędnych ceregieli:
Zauważ, że dodałem parametry domyślne, ponieważ przez większość czasu możesz chcieć traktować ciągi jako wartości, a nie tablice. Podobnie w przypadku krotek.
źródło
źródło
Możesz sprawdzić typ danych zmiennej.
To da ci umieścić jako typ danych P.
Abyś mógł odróżnić, że jest to liczba całkowita lub tablica.
źródło
Dziwi mnie, że takie podstawowe pytanie nie wydaje się mieć bezpośredniej odpowiedzi w pythonie. Wydaje mi się, że prawie wszystkie proponowane odpowiedzi używają pewnego rodzaju sprawdzania typów, co zwykle nie jest zalecane w pythonie i wydają się ograniczone do konkretnego przypadku (zawodzą przy różnych typach liczbowych lub ogólnych iterowalnych obiektach, które nie są krotkami ani listami).
Dla mnie lepiej działa importowanie numpy i używanie array.size, na przykład:
Uwaga:
ale:
źródło
Po prostu użyj
size
zamiastlen
!źródło
np.size(5)
inp.size([5])
oba są ==1
, więc to nie rozróżnia poprawnie typu (tj. identyfikuje skalar), co moim zdaniem jest celem.preds_test [0] ma kształt (128, 128, 1) Pozwala sprawdzić typ danych za pomocą isinstance () funkcja isinstance przyjmuje 2 argumenty. 1. argument to dane 2. argument to typ danych isinstance (preds_test [0], np.ndarray) daje Output jako True. Oznacza to, że preds_test [0] jest tablicą.
źródło
Aby odpowiedzieć na pytanie w tytule, bezpośrednim sposobem ustalenia, czy zmienna jest skalarem, jest próba przekształcenia jej w zmiennoprzecinkową. Jeśli tak
TypeError
, to nie jest.źródło