Python: how to convert a dictionary into a subscriptable array?

Question:

I know how to convert a dictionary into an list in Python, but somehow when I try to get, say, the sum of the resulting list, I get the error 'dict_values' object is not subscriptable. Also, I plan to sum only several items in the list.

dict = {A:1, B:2, C:3, D:4}
arr = dict.values()
the_sum = sum(arr[1:3])

Upon closer inspection, I noticed that when the resulting list is printed out, it always gives dict_values(......) as the output which I can’t remove. How do I get around this?

Asked By: quotable7

||

Answers:

In python-3.X dict.values doesn’t return a list object like how it used to perform in python-2.X. In python-3.x it returns a dict-value object which is a set-like object and uses a hash table for storing its items which is not suitable for indexing. This feature, in addition to supporting most of set attributes, is very optimized for operations like membership checking (using in operator).

If you want to get a list object, you need to convert it to list by passing the result to the list() function.

the_values = dict.values()
SUM = sum(list(the_values)[1:10])
Answered By: Mazdak

Yes, it did appear like a list on the older Python questions asked here. But as @Kasramvd said, assuming you are using python 3.X, dict.values is a dictionary view object.
(Also, you definitely came up with this example hastily as you have four dictionary entries but want 10 list items, which is redundant.)

Answered By: txsaw1

By assigning dict.values() to a list you are not converting it to a list; you are just storing it as dict_values (may be an object). To convert it write value_list=list(dict.values()). Now even while printing the value_list you will get the list elements and not dict_values(......).

And as mentioned before don’t use Python built-in names as your variable names; it may cause conflicts during execution and confusion while reading your code.

Answered By: Devansh Bansal

@mgilson is right. A dictionary , by its intrinsic nature, isn’t ordered.

Still you can do this :

alpha = {"A":1,"B":2,"C":3,"D":4,"E":5}   # dictionary
my_list = []
for key,value in alpha.items() :
    my_list.append(value)

You can access your “values” from my_list, but it will not be in order.

Answered By: sharad jain

Creating a new list using list() constructor, only to slice it is wasteful. Using islice from the built-in itertools module will be more efficient.

from itertools import islice
dct = {'A':1, 'B':2, 'C':3, 'D':4}
arr = dct.values()
the_sum = sum(islice(arr, 1, 3))
the_sum
# 5

The difference is efficiency is noticeable especially if the dictionary is very large but the slice is small relative to it. For example, for a dictionary of 10mil key-value pairs, if you’re slicing 20 pairs and summing their values, islice is ~39400x faster than constructing a list and slicing it.

n = 10_000_000
dct = dict(zip(range(n), [0,1,2,3,4]*(n//5)))

%timeit sum(list(dct.values())[10:30])
# 120 ms ± 813 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
%timeit sum(islice(dct.values(), 10, 30))
# 3.04 µs ± 19.4 ns per loop (mean ± std. dev. of 7 runs, 100 loops each)

Even if the slice is large, islice is still faster (though not as dramatic as a small slice)

%timeit sum(list(dct.values())[1:n])
# 277 ms ± 2.24 ms per loop (mean ± std. dev. of 7 runs, 100 loops each)

%timeit sum(islice(dct.values(), 1, n))
# 181 ms ± 4.9 ms per loop (mean ± std. dev. of 7 runs, 100 loops each)
Answered By: not a robot

Using list(dictObj.values()) to wrap a dict_valuesobject is not always successful, especially if the resulting dict_values list contains different data.

It will throw the Error:

{TypeError} 'generator' object is not callable

If you receive this error try to generate a iterable list using a for comprehension:

[x for x in dictObj.values()]

It will do the job

Answered By: freshNfunky
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.