Q Yang
Q Yang

Reputation: 310

Python dictionary keys() Method

I am trying to figure out when the dictionary keys() method is mandatory. Here is my code.

rawFeats = [(0, 'mouse'), (1, 'black'), (0, 'cat'), (1, 'tabby'), (2, 'mouse')]
OHEDict = {(0, 'cat'): 1, (1, 'tabby'): 4, (2, 'mouse'): 5}
indices = {OHEDict[i]:1.0 for i in rawFeats if i in OHEDict}
indices1 = {OHEDict[i]:1.0 for i in rawFeats if i in OHEDict.keys()}

print "indices = {0}\nindices1 = {1}".format(indices, indices1)

the output is:

indices = {1: 1.0, 4: 1.0, 5: 1.0}
indices1 = {1: 1.0, 4: 1.0, 5: 1.0}

I can understand indices1 work well because (0, 'cat')is one of the keys, but why indices turn out the same result? Any hint will be appreciated. BTW, for large data set, indices's performance is way much better than indices1.

Upvotes: 1

Views: 4102

Answers (3)

mgilson
mgilson

Reputation: 309929

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...

Upvotes: 4

James
James

Reputation: 1238

x in dict where dict is a python dictionary returns True if and only if x is a key for some entry in dict.

Upvotes: 0

Avinash Raj
Avinash Raj

Reputation: 174706

Both refers (iterate over) the dictionary keys only.

for i in dic:

is equal to

for i in dic.keys():

Upvotes: 0

Related Questions