Objetos de vista de diccionario de Python 3.x y matplotlib

En las keys() Python 3.x keys() , los values() y los items() devuelven vistas . Ahora, mientras que las vistas ciertamente tienen ventajas , también parecen causar algunos problemas de compatibilidad. Por ejemplo con matplotlib (en última instancia, es con numpy ). Como ejemplo, esto y las respuestas en las preguntas de stackexchange funcionan bien con python 2.x pero generan una excepción al ejecutarlas en python 3.4.

Un ejemplo mínimo sería:

 import matplotlib.pyplot as plt d = {1: 2, 2: 10} plt.scatter(d.keys(), d.values()) 

Lo que plantea el TypeError: float() argument must be a string or a number, not 'dict_values' con python 3.4.

Mientras que para el ejemplo mínimo la Excepción es bastante clara, esta pregunta surge debido al mismo problema y aquí la Excepción es mucho menos clara: TypeError: ufunc 'isfinite' not supported for the input types, and the inputs could not be safely coerced to any supported types according to the casting rule ''safe''

¿Cuál es la mejor práctica para tratar este problema? ¿Podemos esperar que en una nueva versión de matplotlib (o en última instancia, numpy ) este problema se numpy o deberíamos comenzar a escribir cosas como la list(dict.values()) cuando se usa matplotlib solo para asegurarnos de no tener problemas? con python 3.x?

Más de ese error:

 --> 512 return array(a, dtype, copy=False, order=order, subok=True) 513 514 def ascontiguousarray(a, dtype=None): TypeError: float() argument must be a string or a number, not 'dict_values' 

Entonces el ejemplo mínimo es:

 np.array(d.keys(),dtype=float) 

Sin la especificación dtype

 In [16]: np.array(d.keys()) Out[16]: array(dict_keys([1, 3]), dtype=object) 

Las dict_keys se tratan como un object . Por lo general, debe trabajar para evitar que np.array trate un objeto como una lista de números.

 In [17]: np.fromiter(d.keys(),dtype=float) Out[17]: array([ 1., 3.]) 

np.fromiter puede manejar d.keys() , tratándolo como un iterable. Así que hay algunos detalles sobre cómo fromiter maneja un iterable que es diferente de np.array .

Una expresión generadora funciona de la misma manera, por ejemplo (i for i in range(4)) . fromiter puede iterar a través de él, la array lo trata como un objeto o genera un error.

Si todos los errores que el SO mencionado se redujeron a np.array(...) manejar un generador, entonces es posible corregir el comportamiento con un numpy cambio de número. Los desarrolladores ciertamente no querrían modificar cada función y método que pueda aceptar una lista. Pero se siente como un cambio fundamental que debería ser probado a fondo. E incluso entonces es probable que produzca problemas de compatibilidad hacia atrás.

La solución aceptada, desde hace algún tiempo, ha sido pasar su código a través de 2to3 .

https://docs.python.org/2/library/2to3.html

para los diccionarios:

Corrige los métodos de iteración del diccionario. dict.iteritems () se convierte en dict.items (), dict.iterkeys () en dict.keys () y dict.itervalues ​​() en dict.values ​​(). De manera similar, dict.viewitems (), dict.viewkeys () y dict.viewvalues ​​() se convierten respectivamente en dict.items (), dict.keys () y dict.values ​​(). También envuelve los usos existentes de dict.items (), dict.keys () y dict.values ​​() en una llamada a la lista.