python: cómo identificar si una variable es un array o un escalar
Tengo una función que toma el argumento NBins
. Quiero hacer una llamada a esta función con un escalar 50
o un array [0, 10, 20, 30]
. ¿Cómo puedo identificar dentro de la función, cuál es la longitud de NBins
? o dicho de otra manera, si es un escalar o un vector?
He intentado 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 ves, no puedo aplicar len
a P
, ya que no es un array.... Hay algo como isarray
o isscalar
en python?
Gracias
10 answers
>>> isinstance([0, 10, 20, 30], list)
True
>>> isinstance(50, list)
False
Para soportar cualquier tipo de secuencia, marque collections.Sequence
en lugar de list
.
Nota: isinstance
también soporta una tupla de clases, check type(x) in (..., ...)
debe evitarse y es innecesario.
Es posible que también desee comprobar not isinstance(x, (str, unicode))
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-02-10 11:04:49
Las respuestas anteriores asumen que la matriz es una lista estándar de python. Como alguien que usa numpy a menudo, recomendaría una prueba muy pitónica de:
if hasattr(N, "__len__")
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-11-04 17:32:06
Combinando las respuestas de @jamylak y @jpaddison3 juntas, si necesita ser robusto contra matrices numpy como entrada y manejarlas de la misma manera que las listas, debe usar{[15]]}
import numpy as np
isinstance(P, (list, tuple, np.ndarray))
Esto es robusto contra subclases de matrices list, tupla y numpy.
Y si desea ser robusto contra todas las demás subclases de secuencia también (no solo lista y tupla), use
import collections
import numpy as np
isinstance(P, (collections.Sequence, np.ndarray))
¿Por qué hacer las cosas de esta manera con isinstance
y no comparar type(P)
con un valor objetivo? Aquí hay un ejemplo, donde hacemos y estudiamos el comportamiento de NewList
, una subclase trivial de list.
>>> 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
se comparen como iguales, manejarlos por type
resultaría en un comportamiento diferente. Sin embargo, dado que x
es una instancia de una subclase de list
, usar isinstance(x,list)
da el comportamiento deseado y trata x
y y
de la misma manera.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-02-02 16:29:26
¿Hay un equivalente a isscalar() en numpy? Sí.
>>> np.isscalar(3.1)
True
>>> np.isscalar([3.1])
False
>>> np.isscalar(False)
True
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-11-13 04:53:17
Si bien 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
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-05-29 06:37:21
Otro enfoque alternativo (uso de la clase nombre propiedad):
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.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-05-29 07:13:58
Simplemente use size
en 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
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
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
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-05-29 06:40:59
Puede comprobar el tipo de datos de la variable.
N = [2,3,5]
P = 5
type(P)
Se le dará a cabo poner como tipo de datos de P.
<type 'int'>
Para que pueda diferenciar que es un entero o una matriz.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-05-29 06:54:11
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 tipo comprobación, que generalmente no se aconseja en python y parecen restringidos a un caso específico (fallan con diferentes tipos numéricos u objetos iterables genéricos que no son tuplas o listas).
Para mí, lo que funciona mejor es importar numpy y usar array.tamaño, 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
Nota 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
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-08-29 16:35:52