transpuesta - python: cómo identificar si una variable es una matriz o un escalar
norma de una matriz en python (10)
Tengo una función que toma el argumento NBins
. Quiero hacer una llamada a esta función con un escalar 50
o una matriz [0, 10, 20, 30]
. ¿Cómo puedo identificar dentro de la función, cuál es la longitud de los NBins
? ¿O dicho de otra manera, si es un escalar o un vector?
Intenté esto:
>>> 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()
>>>
Como puede ver, no puedo aplicar len
a P
, ya que no es una matriz ... ¿Hay algo como isarray
o isscalar
en python?
Gracias
¿Hay un equivalente a isscalar () en numpy? Sí.
>>> np.isscalar(3.1)
True
>>> np.isscalar([3.1])
False
>>> np.isscalar(False)
True
Combinando las respuestas de @jamylak y @ jpaddison3 juntas, si necesita ser robusto contra las matrices numpy como entrada y manejarlas de la misma manera que en las listas, debe usar
import numpy as np
isinstance(P, (list, tuple, np.ndarray))
Esto es robusto contra las subclases de arrays de listas, tuplas y números.
Y si también quiere ser sólido contra todas las demás subclases de secuencia (no solo lista y tupla), use
import collections
import numpy as np
isinstance(P, (collections.Sequence, np.ndarray))
¿Por qué debería hacer las cosas de esta manera con isinstance
y no comparar el type(P)
con un valor objetivo? Aquí hay un ejemplo, donde hacemos y estudiamos el comportamiento de NewList
, una subclase trivial de la lista.
>>> 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
A pesar de que x
y y
comparan como iguales, manejarlos por type
daría como resultado un comportamiento diferente. Sin embargo, dado que x
es una instancia de una subclase de list
, usar isinstance(x,list)
proporciona el comportamiento deseado y trata x
e y
de la misma manera.
Las respuestas anteriores asumen que la matriz es una lista estándar de python. Como alguien que usa el adormecimiento a menudo, recomiendo una prueba muy pitónica de:
if hasattr(N, "__len__")
Me sorprende que una pregunta tan básica no parezca tener una respuesta inmediata en Python. Me parece que casi todas las respuestas propuestas utilizan algún tipo de verificación de tipo, que generalmente no se recomienda en python y parecen restringidas a un caso específico (fallan con diferentes tipos numéricos u objetos iteratables genéricos que no son tuplas o listas).
Para mí, lo que funciona mejor es importar numpy y usar array.size, por ejemplo:
>>> 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
Tenga en cuenta también:
>>> len(np.array([1,2]))
Out[5]: 2
pero:
>>> 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
Mientras que, el enfoque de @ jamylak es el mejor, aquí hay un enfoque alternativo
>>> N=[2,3,5]
>>> P = 5
>>> type(P) in (tuple, list)
False
>>> type(N) in (tuple, list)
True
Otro enfoque alternativo (uso de propiedad de nombre de clase):
N = [2,3,5]
P = 5
type(N).__name__ == ''list''
True
type(P).__name__ == ''int''
True
type(N).__name__ in (''list'', ''tuple'')
True
No hay necesidad de importar nada.
Puede comprobar el tipo de datos de la variable.
N = [2,3,5]
P = 5
type(P)
Se le dará a conocer como tipo de datos de P.
<type ''int''>
Para que puedas diferenciarlo es un entero o una matriz.
Simplemente usa size
lugar de 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
>>> N=[2,3,5]
>>> P = 5
>>> type(P)==type(0)
True
>>> type([1,2])==type(N)
True
>>> type(P)==type([1,2])
False
>>> isinstance([0, 10, 20, 30], list)
True
>>> isinstance(50, list)
False
Para admitir cualquier tipo de secuencia, verifique las collections.Sequence
Secuencia en lugar de list
.
nota : isinstance
también admite una tupla de clases, debe evitarse el type(x) in (..., ...)
cheque type(x) in (..., ...)
y no es necesario.
También puede querer verificar not isinstance(x, (str, unicode))