La réponse de Joachim Sauer explique très bien pourquoi un list
n'est pas retourné. Mais ceci laisse la question de savoir pourquoi ces fonctions ne retourneraient pas les itérateurs, tout comme iteritems
etc. en Python 2.
Un itérateur est beaucoup plus restrictif qu'un conteneur. Par exemple, un itérateur n'autorise pas plus d'un passage; Si vous essayez un second passage, vous trouverez qu'il est vide. Par conséquent, les opérations telles que elem in cont
sont prises en charge par les conteneurs, mais ne peuvent pas être prises en charge par les itérateurs: une fois que vous vérifiez si un élément est "dans" l'itérateur, l'itérateur est détruit! D'autre part, obtenir un conteneur habituellement nécessite d'effectuer une copie telle que la création d'une liste à partir des clés du dictionnaire. L'objet view
a le meilleur des deux mondes: il se comporte comme un conteneur et ne fait pas de copie du dictionnaire! C'est, en fait, une sorte de conteneur virtuel en lecture seule qui fonctionne en liant le dictionnaire sous-jacent. Je ne sais pas si c'est vu ailleurs dans le standard Python.
Edit:
@AntonyHatchkins: la raison pour laquelle il ne retourne pas une fonction de générateur est qu'il ne permettrait pas une opération in
rapide. Oui, in
fonctionne pour les fonctions du générateur (quand vous les appelez). Autrement dit, vous pouvez le faire:
def f():
for i in range(10):
yield i
5 in f() # True
Mais selon la définition de in
, si le côté droit est un générateur, python passera par tous les n
éléments du générateur - conduisant à O(n)
la complexité du temps. Il n'y a rien que vous puissiez faire parce que c'est le seul comportement significatif un générateur arbitraire.D'autre part, dans le cas de l'affichage du dictionnaire, vous pouvez implémenter in
comme vous le souhaitez, car vous en savez plus sur les données que vous gérez. Et en fait in
est mis en œuvre avec O(1)
complexité en utilisant une table de hachage. Vous pouvez le vérifier en exécutant
>>> d = dict(zip(range(50000000), range(50000000)))
>>> 49999999 in d
True
>>> 49999999 in iter(d) # kinda how generator function would work
True
>>>
et en remarquant à quelle vitesse la première in
est comparée à la seconde in
.
Ceci est une excellente réponse sur StackOverflow: http://stackoverflow.com/questions/8957750/what-are-python-dictionary-view-objects – Exthen
On dirait que l'url est mort. – Borealis