Ich habe eine Funktion, die das Argument NBins akzeptiert. Ich möchte diese Funktion mit einem Skalar 50 oder einem Array [0, 10, 20, 30] aufrufen. Wie kann ich innerhalb der Funktion feststellen, wie lang NBins ist? oder anders gesagt, wenn es ein Skalar oder ein Vektor ist?

Ich habe es versucht:

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

Wie Sie sehen, kann ich len nicht auf P anwenden, da es sich nicht um ein Array handelt. Gibt es in Python so etwas wie isarray oder isscalar?

Vielen Dank

271
otmezger 29 Mai 2013 im 10:33

12 Antworten

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

Um jede Art von Sequenz zu unterstützen, aktivieren Sie collections.Sequence anstelle von list.

Hinweis : isinstance unterstützt auch ein Tupel von Klassen. Überprüfen Sie, ob type(x) in (..., ...) vermieden werden sollte und nicht erforderlich ist.

Sie können auch not isinstance(x, (str, unicode)) überprüfen

366
jamylak 10 Feb. 2015 im 11:04

Hier ist der beste Ansatz, den ich gefunden habe: Überprüfen Sie die Existenz von __len__ und __getitem__.

Sie fragen sich vielleicht warum? Die Gründe umfassen:

  1. Die beliebte Methode isinstance(obj, abc.Sequence) schlägt bei einigen Objekten, einschließlich PyTorchs Tensor, fehl, da sie __contains__ nicht implementieren.
  2. Leider gibt es in Pythons collection.abc nichts, was nur nach __len__ und __getitem__ sucht, was meiner Meinung nach minimale Methoden für Array-ähnliche Objekte sind.
  3. Es funktioniert auf Liste, Tupel, Ndarray, Tensor usw.

Also ohne weiteres:

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

Beachten Sie, dass ich Standardparameter hinzugefügt habe, da Sie Zeichenfolgen meistens als Werte und nicht als Arrays betrachten möchten. Ähnliches gilt für Tupel.

2
Shital Shah 7 Jän. 2020 im 09:06

Ich bin überrascht, dass eine so grundlegende Frage in Python keine unmittelbare Antwort zu haben scheint. Es scheint mir, dass fast alle vorgeschlagenen Antworten eine Art Typprüfung verwenden, die in Python normalerweise nicht empfohlen wird, und sie scheinen auf einen bestimmten Fall beschränkt zu sein (sie schlagen mit verschiedenen numerischen Typen oder generischen iterierbaren Objekten fehl, die keine Tupel oder Listen sind).

Für mich funktioniert es besser, numpy zu importieren und array.size zu verwenden, zum Beispiel:

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

Beachten Sie auch:

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

Out[5]: 2

Aber:

>>> 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
2
Vincenzooo 29 Aug. 2015 im 16:35

Preds_test [0] hat die Form (128,128,1). Überprüfen Sie den Datentyp mithilfe der Funktion isinstance (). isinstance akzeptiert 2 Argumente. 1. Argument ist Daten 2. Argument ist Datentyp isinstance (preds_test [0], np.ndarray) gibt Output als True aus. Dies bedeutet, dass preds_test [0] ein Array ist.

0
Sumanth Meenan 8 Juni 2019 im 10:07

Wenn Sie die Antworten von @jamylak und @ jpaddison3 miteinander kombinieren, sollten Sie sie verwenden, wenn Sie gegenüber numpy-Arrays als Eingabe robust sein und sie wie Listen behandeln möchten

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

Dies ist robust gegenüber Unterklassen von Listen-, Tupel- und Numpy-Arrays.

Und wenn Sie auch gegenüber allen anderen Sequenzunterklassen (nicht nur Liste und Tupel) robust sein möchten, verwenden Sie

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

Warum sollten Sie mit isinstance so vorgehen und type(P) nicht mit einem Zielwert vergleichen? Hier ist ein Beispiel, in dem wir das Verhalten von NewList, einer trivialen Unterklasse von Listen, erstellen und untersuchen.

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

Obwohl x und y als gleich verglichen werden, würde die Behandlung mit type zu einem unterschiedlichen Verhalten führen. Da x jedoch eine Instanz einer Unterklasse von list ist, ergibt die Verwendung von isinstance(x,list) das gewünschte Verhalten und behandelt x und y auf dieselbe Weise.

42
scottclowe 2 Feb. 2016 im 16:29

Gibt es ein Äquivalent zu isscalar () in numpy? Ja.

>>> np.isscalar(3.1)
True
>>> np.isscalar([3.1])
False
>>> np.isscalar(False)
True
31
jmhl 13 Nov. 2015 im 04:53

Verwenden Sie einfach size anstelle von 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
Mathieu Villion 4 Dez. 2016 im 09:56

Während @ jamylaks Ansatz der bessere ist, gibt es hier einen alternativen Ansatz

>>> N=[2,3,5]
>>> P = 5
>>> type(P) in (tuple, list)
False
>>> type(N) in (tuple, list)
True
17
Sukrit Kalra 29 Mai 2013 im 06:37
>>> N=[2,3,5]
>>> P = 5
>>> type(P)==type(0)
True
>>> type([1,2])==type(N)
True
>>> type(P)==type([1,2])
False
2
suhailvs 29 Mai 2013 im 06:40

Ein anderer alternativer Ansatz (Verwendung der Eigenschaft class name ):

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

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

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

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

Sie müssen nichts importieren.

3
Marek 29 Mai 2013 im 07:13

Sie können den Datentyp der Variablen überprüfen.

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

Es wird Ihnen als Datentyp von P ausgegeben.

<type 'int'>

Damit Sie unterscheiden können, dass es sich um eine Ganzzahl oder ein Array handelt.

2
unnati patil 29 Mai 2013 im 06:54

Bei früheren Antworten wird davon ausgegangen, dass das Array eine Python-Standardliste ist. Als jemand, der häufig Numpy verwendet, würde ich einen sehr pythonischen Test empfehlen von:

if hasattr(N, "__len__")
113
jpaddison3 4 Nov. 2013 im 17:32