This will convert the dict_keys object to a list:
Copylist(newdict.keys())
On the other hand, you should ask yourself whether or not it matters. It is Pythonic to assume duck typing -- if it looks like a duck and it quacks like a duck, it is a duck. The dict_keys object can be iterated over just like a list. For instance:
Copyfor key in newdict.keys():
print(key)
Note that dict_keys doesn't support insertion newdict[k] = v, though you may not need it.
How do I return dictionary keys as a list in Python? - Stack Overflow
Python dictionary keys() Method - Stack Overflow
list - Understanding accessing the key and value in dictionaries Python - Stack Overflow
Python dictionary keys "new" syntax
Videos
This will convert the dict_keys object to a list:
Copylist(newdict.keys())
On the other hand, you should ask yourself whether or not it matters. It is Pythonic to assume duck typing -- if it looks like a duck and it quacks like a duck, it is a duck. The dict_keys object can be iterated over just like a list. For instance:
Copyfor key in newdict.keys():
print(key)
Note that dict_keys doesn't support insertion newdict[k] = v, though you may not need it.
Python >= 3.5 alternative: unpack into a list literal [*newdict]
New unpacking generalizations (PEP 448) were introduced with Python 3.5 allowing you to now easily do:
Copy>>> newdict = {1:0, 2:0, 3:0}
>>> [*newdict]
[1, 2, 3]
Unpacking with * works with any object that is iterable and, since dictionaries return their keys when iterated through, you can easily create a list by using it within a list literal.
Adding .keys() i.e [*newdict.keys()] might help in making your intent a bit more explicit though it will cost you a function look-up and invocation. (which, in all honesty, isn't something you should really be worried about).
The *iterable syntax is similar to doing list(iterable) and its behaviour was initially documented in the Calls section of the Python Reference manual. With PEP 448 the restriction on where *iterable could appear was loosened allowing it to also be placed in list, set and tuple literals, the reference manual on Expression lists was also updated to state this.
Though equivalent to list(newdict) with the difference that it's faster (at least for small dictionaries) because no function call is actually performed:
Copy%timeit [*newdict]
1000000 loops, best of 3: 249 ns per loop
%timeit list(newdict)
1000000 loops, best of 3: 508 ns per loop
%timeit [k for k in newdict]
1000000 loops, best of 3: 574 ns per loop
with larger dictionaries the speed is pretty much the same (the overhead of iterating through a large collection trumps the small cost of a function call).
In a similar fashion, you can create tuples and sets of dictionary keys:
Copy>>> *newdict,
(1, 2, 3)
>>> {*newdict}
{1, 2, 3}
beware of the trailing comma in the tuple case!
On python2.x, dict.keys is (IMHO) more or less worthless. You can iterate over a dictionary's keys directly:
for key in d:
...
which will be more efficient than iterating over the keys:
for key in d.keys():
...
which makes a separate list, and then iterates over it -- effectively doing the iteration twice + a bunch of extra memory overhead of having a throw-away list, etc, etc.
Your use-case is actually doing a membership test on the keys. It's the difference between:
x in some_list # is "x" an item in the list?
and
x in some_dict # is "x" a key in the dictionary?
Membership tests on list objects are O(N) but on dict are O(1). So, for every "turn" of the loop, you're doing an O(N) list construction and an O(N) lookup to see if the item is in the list instead of a simple O(1) hash lookup of the key.
It should be noted If you ever do actually need a list of a dictionary's keys, you could get it easily1:
list(d)
Fortunately, python3.x has taken steps in the correct direction. d.keys() returns a set-like object in python3.x. You can use this to efficiently calculate the intersection of two dictionaries' keys for example which can be useful in some situations.
It's also worth pointing out that the set like object in python3.x (called a dict_keys object) also has O(1) membership testing (as is to be expected of something that looks like a set), compared to the O(n) membership test of a list.
1This, consequentially, works in python2.x and python3.x so it's a nice thing to remember when you're trying to write code that is compatible with either...
Both refers (iterate over) the dictionary keys only.
for i in dic:
is equal to
for i in dic.keys():
To loop over the keys you do:
Copyfor k in golds.keys():
For the values:
Copyfor v in golds.values():
And for both:
Copyfor k, v in golds.items():
The Python creators had to choose one of the above to be the default experience when doing for item in golds. They decided upon the first one.
But why?
As the Sven and Amitai have pointed out, making it the default behavior to iterate over the keys is consistent with the ability to do key in my_dict. The more I think about it, value in my_dict would have just been a bad idea.
Also, I think Python wanted to be consistent with the way many other languages handled the situation at that time, so that brings up the question, which major language was the first one to loop over dictionaries? I tried to do some research to figure this out, but I couldn't find out which language was the first to make this choice :(
When iterating of a dictionary, you will be iterating over the keys only. Your piece of code:
Copyfor item in golds:
countries.append(item)
does just that.
A much simpler way of doing this would be simply:
Copycountries = list(golds)
because the list constructor iterates over a sequence, and in the case of a dict, that means its keys. While the above works, it is a bit obscure. A better options would be:
Copycountries = list(golds.keys())
The keys method returns a sequence (iterator in Python 3, simply a list in Python 2) of all the dictionary keys. This is better (IMHO) than the previous method, because it clearly states the intent of the code, making it more readable.
hey
just found out you can use tuples as dictionary keys which saved me doing a lot of weird workarounds.
any other useful hidden gems in pythons syntax?
thanks!