Reputation: 1695
def shuffle(self, x, random=None, int=int):
"""x, random=random.random -> shuffle list x in place; return None.
Optional arg random is a 0-argument function returning a random
float in [0.0, 1.0); by default, the standard random.random.
"""
randbelow = self._randbelow
for i in reversed(range(1, len(x))):
# pick an element in x[:i+1] with which to exchange x[i]
j = randbelow(i+1) if random is None else int(random() * (i+1))
x[i], x[j] = x[j], x[i]
When I run the shuffle
function it raises the following error, why is that?
TypeError: 'dict_keys' object does not support indexing
Upvotes: 169
Views: 164291
Reputation: 679
Convert an iterable to a list may have a cost. Instead, to get the the first item, you can use:
next(iter(keys))
Or, if you want to iterate over all items, you can use:
items = iter(keys)
while True:
try:
item = next(items)
except StopIteration as e:
pass # finish
Upvotes: 13
Reputation: 362
In Python 2 dict.keys() return a list, whereas in Python 3 it returns a generator.
You could only iterate over it's values else you may have to explicitly convert it to a list i.e. pass it to a list function.
Upvotes: 1
Reputation: 2901
Why you need to implement shuffle when it already exists? Stay on the shoulders of giants.
import random
d1 = {0:'zero', 1:'one', 2:'two', 3:'three', 4:'four',
5:'five', 6:'six', 7:'seven', 8:'eight', 9:'nine'}
keys = list(d1)
random.shuffle(keys)
d2 = {}
for key in keys: d2[key] = d1[key]
print(d1)
print(d2)
Upvotes: 0
Reputation: 309889
Clearly you're passing in d.keys()
to your shuffle
function. Probably this was written with python2.x (when d.keys()
returned a list). With python3.x, d.keys()
returns a dict_keys
object which behaves a lot more like a set
than a list
. As such, it can't be indexed.
The solution is to pass list(d.keys())
(or simply list(d)
) to shuffle
.
Upvotes: 264
Reputation: 154886
You're passing the result of somedict.keys()
to the function. In Python 3, dict.keys
doesn't return a list, but a set-like object that represents a view of the dictionary's keys and (being set-like) doesn't support indexing.
To fix the problem, use list(somedict.keys())
to collect the keys, and work with that.
Upvotes: 13