Подтвердить что ты не робот

Объекты просмотра Python 3.x и matplotlib

В python 3.x keys(), values() и items() верните views. Теперь, когда мнения, безусловно, имеют преимущества, они также, похоже, вызывают некоторые проблемы совместимости. Например, с matplotlib (в конечном счете это с numpy). В качестве примера this и this ответы на вопросы о stackexchange работают нормально с python 2.x, но вызывают исключение при выполнении их в python 3.4.

Минимальным примером может быть:

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

Что повышает TypeError: float() argument must be a string or a number, not 'dict_values' с помощью python 3.4.

В то время как для минимального примера Исключение совершенно ясное, вопрос this возникает из-за той же проблемы, и здесь Исключение намного менее ясное: 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''

Какова наилучшая практика для решения этой проблемы? Можем ли мы надеяться, что в новой версии matplotlib (или, в конечном счете, numpy) эта проблема будет решена или мы должны начать писать такие вещи, как list(dict.values()) при использовании matplotlib, чтобы убедиться, проблема с python 3.x?

4b9b3361

Ответ 1

Больше этой ошибки:

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

Итак, минимальный пример:

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

Без спецификации dtype

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

dict_keys рассматривается как object. Обычно вам нужно работать с тем, чтобы np.array не обрабатывать объект как список чисел.

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

np.fromiter может обрабатывать d.keys(), рассматривая его как итеративный. Итак, некоторые детали в том, как fromiter обрабатывает итерируемый, отличный от np.array.

Выражение генератора работает одинаково, например. (i for i in range(4)). fromiter может проходить через него, array либо рассматривает его как объект, либо вызывает ошибку.

Если все ошибки, о которых упоминалось в SO, сводились к np.array(...) обработке генератора, тогда было бы возможно исправить поведение с одним изменением numpy. Разработчики, конечно же, не хотели бы настраивать каждую функцию и метод, которые могли бы принять список. Но это похоже на фундаментальное изменение, которое должно быть тщательно проверено. И даже тогда это может вызвать проблемы с обратной совместимостью.

Принятое решение в течение некоторого времени должно было передать ваш код через 2to3.

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

для словарей:

Исправляет методы итерации словаря. dict.iteritems() преобразуется в dict.items(), dict.iterkeys() в dict.keys() и dict.itervalues ​​() в dict.values ​​(). Аналогично, dict.viewitems(), dict.viewkeys() и dict.viewvalues ​​() преобразуются соответственно в dict.items(), dict.keys() и dict.values ​​(). Он также переносит существующие обычаи dict.items(), dict.keys() и dict.values ​​() в вызове списка.