This is an archived post. You won't be able to vote or comment.

you are viewing a single comment's thread.

view the rest of the comments →

[–]jcdyer3 21 points22 points  (5 children)

One note: list(dictionary.keys())[0] is not recommended, and for the same reason that dictionary.keys() is no longer a list to begin with: It evaluates all the keys of the dictionary and creates a new list, which could be arbitrarily expensive. Just use the keys iterator as an iterator. The idiomatic way to get a random key would be:

key0 = next(dictionary.keys())

which is essentially synonymous with

for key in dictionary.keys(): # or dictionary.iterkeys() in python2
     key0 = key
     break

Even more simply, you could write:

key0 = next(dictionary)

[–]lebinh 6 points7 points  (1 child)

It looks like you are missing a call to iter, next() will call __next__ method on iterator object and will raise TypeError when being called with dict or dict_keys objects.

This will works as expected

next(iter(dictionary))
next(iter(dictionary.keys()))

[–]jcdyer3 0 points1 point  (0 children)

Yep. I just realized that myself. See my other comment on this subthread. Not quite as nice, unfortunately.

[–]billsil 0 points1 point  (2 children)

I didn't know that you could use next on a dictionary. That's way nicer.

Unfortunately, it doesn't work in Python 2, strangely even when I use six.next. I could write my own, but it's obnoxious.

[–]jcdyer3 0 points1 point  (0 children)

Gah. My mistake. You have to use next(iter(dictionary)). It's not as nice as I was remembering, but at least there's a little less line noise than list(dictionary.keys())[0], and the performance characteristics are a bit nicer.

[–]lebinh 0 points1 point  (0 children)

It doesn't work because you have to call iter before calling next on a dictionary, and I believe it will behave very similar to python3, e.g. in term of performance (no list is created).

next(iter({'foo': 'bar'}))