2015-07-31 11 views
13

W pythonie 3.x keys(), values() i items() return views. Teraz, podczas gdy widoki z pewnością mają advantages, wydają się powodować pewne problemy ze zgodnością. Na przykład z matplotlib (ostatecznie jest to z numpy). Na przykład, odpowiedzi na pytania dotyczące stosu zmiennych na poziomie this i this działają dobrze z pythonem 2.x, ale podnoszą wyjątek podczas wykonywania ich w pythonie 3.4.Obiekty widoku języka Python 3.x i matplotlib

Minimalny Przykładem może być:

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

co podnosi TypeError: float() argument must be a string or a number, not 'dict_values' z Pythona 3.4.

Choć na minimalnym przykład Wyjątkiem jest całkiem jasne, powstaje pytanie this z powodu tego samego problemu i tutaj wyjątkiem jest dużo mniej oczywiste: 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''

Jaka jest najlepsza praktyka, aby poradzić sobie z tym problemem? Czy możemy mieć nadzieję, że w nowej wersji matplotlib (lub ostatecznie numpy) ten problem zostanie rozwiązany, czy powinniśmy zacząć pisać takie rzeczy jak list(dict.values()) podczas korzystania z matplotlib tylko po to, aby nie napotkać problemów z python 3.x?

+1

Jest to bardzo interesujący punkt, ale pytanie jest prawie całkowicie kwestia opinii. Podnosiłbym go z deweloperami matplotlib/zgłosiłem problem na githubie. Wydaje mi się, że twoje obejście wygląda na rozsądne (tzn. Stwórz listę z wartości), ale ostatecznie poprawka matplotlib/numpy byłaby miła. Niestety nie sądzę, aby pytanie pasowało do formatu przepełnienia stosu lub zasad dotyczących pytań opartych na opiniach. –

+1

@JRichardSnape: Na pewno masz rację, ponieważ to pytanie jest dla większości z nas oparte głównie na opiniach. Jeśli chodzi o to, jak sobie poradzić z sytuacją taką, jaka jest obecnie, to jest kwestia gustu i nie jest to bardzo istotne pytanie, jeśli chodzi o to, czy i jak problem ten zostanie rozwiązany przez "numpy" lub 'matplotlib' faceci, ma to niewiele wspólnego z osobistą opinią. Więc nie zgadzam się z tobą tutaj. – jojo

+1

Pewnie, ale domyślam się, że mówię, że przeciętny autor odpowiedzi nie może powiedzieć, co autorzy biblioteki zamierzają zrobić (jeśli w ogóle). W każdym razie, domyślamy się, czy pojawi się dev, który może odpowiedzieć na tę część. –

Odpowiedz

3

więcej tego błędu:

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

Zatem minimalna przykładem jest:

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

Bez opisie dtype

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

dict_keys jest traktowany jako object. Zwykle musisz pracować, aby np.array traktować obiekt jako listę liczb.

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

np.fromiter może obsługiwać d.keys(), traktując je jako iterowalny. Jest więc trochę szczegółów na temat tego, jak fromiter obsługuje iterację różniącą się od np.array.

Wyrażenie generatora działa w ten sam sposób, np. (i for i in range(4)). fromiter może iterować przez to, array traktuje to jako obiekt lub powoduje błąd.

Jeśli wszystkie błędy, o których wspomniał SO, sprowadzały się do np.array(...) z obsługą generatora, to może być możliwe naprawienie tego zachowania za pomocą jednej zmiany numpy. Deweloperzy z pewnością nie będą chcieli ulepszyć każdej funkcji i metody, która mogłaby zaakceptować listę. Ale wydaje się, że to fundamentalna zmiana, którą należałoby dokładnie przetestować. I nawet wtedy może powodować problemy ze zgodnością wsteczną.

Zaakceptowana poprawka, od jakiegoś czasu, polegała na przekazywaniu kodu przez 2to3.

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

do słowników:

Fixes dictionary iteration methods. dict.iteritems() is converted to dict.items(), dict.iterkeys() to dict.keys(), and dict.itervalues() to dict.values(). Similarly, dict.viewitems(), dict.viewkeys() and dict.viewvalues() are converted respectively to dict.items(), dict.keys() and dict.values(). It also wraps existing usages of dict.items(), dict.keys(), and dict.values() in a call to list.

Powiązane problemy