Nathan Herring Nathan Herring - 1 month ago 25
Python Question

What can you do with a PyDictValues_Type?

While trying to convert some Python/C API code to work in both 2 & 3, I found that, given the following Python

DICT = { … }

class Example(object):
ITEMS = DICT.values()


and then calling
PyObject_GetAttrString(an_example, "ITEMS")
would yield a
PyObject
for which
PySequence_Check
would return true in 2.7. Now in 3.4, it's yielding a
PyObject
whose type is
PyDictValues_Type
and
PySequence_Check
doesn't return true. The documentation on
PyDictValues
is, ahem, sparse. What can one do with it? It also response false to
PyIter_Check
.

Answer

In Python 2, dict.values() returns a list, but in Python 3, it's a view of dictionary values. The equivalent in Python 2.7 is dict.viewvalues().

In particular views are not sequences because dictionaries don't have orders. So dict.viewkeys() and dict.viewitems() are set-like, because keys have to be unique. dict.viewvalues() is multi-set-like. You can iterate over it, get the length, and do contains checks against it. But you can't index into it like a sequence.