简体   繁体   中英

Key in dict.keys(), but dict.get(key) returns None

I have a dictionary of dictionaries ie dict[key1][key2] should return a number. If I do key2 in dict[key1] this returns True , but dict[key1].get(key2) returns None .

I guess there is something quite fundamental I'm missing here, but I'm stuck.

As key1 is a string , and key2 is a numpy.datetime64 .

edit:

key type: <type 'numpy.datetime64'>
key: 2014-08-11T02:00:00.000000+0200
Dict: {numpy.datetime64('2014-08-11T02:00:00.000000000+0200'): 1}
key in dict.keys() True
dict.items(): [(numpy.datetime64('2014-08-11T02:00:00.000000000+0200'), 1)]
dict.get(key): None

edit 2:

replaced by edit 3

Edit 3 (replacing edit 2):

Code:

vessel = df['Vessel'].iloc[0]
print "vessel:",vessel
ati = np.datetime64(df['ATI'].iloc[0])
print "ati type:",type(ati),"value:",ati
print "Self.sailing[vessel]:",self.sailing[vessel]
print "key in dict.keys():",ati in self.sailing[vessel].keys()
sailing = self.sailing[vessel].get(ati)
print "sailing:", sailing
print "dict[key]:",self.sailing[vessel][ati]

Output:

vessel: VESSEL2
ati type: <type 'numpy.datetime64'> value: 2014-07-21T02:00:00.000000+0200
Self.sailing[vessel]: {numpy.datetime64('2014-07-21T02:00:00.000000000+0200'): 1}
key in dict.keys(): True
sailing: None
dict[key]:
Traceback (most recent call last):
  File "C:/dev/python/bmw_vpc/src/vpc_data_extractor.py", line 9, in <module>
    data.create_master_file()
  File "C:\dev\python\bmw_vpc\src\process.py", line 112, in create_master_file
    print "dict[key]:",self.sailing[vessel][ati]
KeyError: numpy.datetime64('2014-07-21T02:00:00.000000+0200')

edit 4:

code:

for key in self.sailing[vessel].keys():
    print "Vessel:",vessel,"ati:",ati,"ati == key:",ati == key
sailing = self.sailing[vessel].get(ati)
print "Vessel:",vessel,"sailing:", sailing

output:

Vessel: VESSEL2 ati: 2014-07-21T02:00:00.000000+0200 ati == key: True
Vessel: VESSEL2 sailing: None

edit 5:

Thanks to @jamylak's answer I made a workaround using the Timestamp instead of the the datetime64-object.

The only option from the information you have given is that key2 exists in dict[key1] and key2 has a value of None

EDIT:

They are 2 completely different objects that just happen to look like the exact same object.

From your code there is:

numpy.datetime64('2014-07-21T02:00:00.000000+0200')

and

numpy.datetime64('2014-07-21T02:00:00.000000000+0200')

>>> (hash(numpy.datetime64('2014-07-21T02:00:00.000000000+0200'))
  == hash(numpy.datetime64('2014-07-21T02:00:00.000000+0200')))
False

The reason this is, is because when you check in dict.keys() it does an equality check ( == ) on each element in a list that is built by the .keys() method and

numpy.datetime64('2014-07-21T02:00:00.000000000+0200') == numpy.datetime64('2014-07-21T02:00:00.000000+0200')

If you try running key in dict , it will return False because that doesnt build the intermediary list and instead uses hash

They are different objects to the dictionary because the hash is what the dictionary uses which is why in dict.keys() does not work.

.get also does not find it because it returns None , you can change the default None to something else to prove this.


As for the reason why they compare equal and have a different hash , I think some sort of bug.

I have tried the following section of code with no issue. Can you follow through and see if you still get the same issue?

Python 2.7.6 (default, Mar 22 2014, 22:59:56) 
[GCC 4.8.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import numpy
>>> k = numpy.datetime64("2014-08-11T02:00:00.000000000+0200")
>>> print k
2014-08-11T08:00:00.000000000+0800
>>> dic = {"k":{k:1}}
>>> print dic
{'k': {numpy.datetime64('2014-08-11T08:00:00.000000000+0800'): 1}}
>>> dic.items()
[('k', {numpy.datetime64('2014-08-11T08:00:00.000000000+0800'): 1})]
>>> dic["k"].items()
[(numpy.datetime64('2014-08-11T08:00:00.000000000+0800'), 1)]
>>> dic["k"].get(k)
1
>>> 

You could try to use get twice:

dictionary.get('key1', {}).get('key2')

This will return None if key1 or key2 does not exist.

A valid example of what probably happen in your script:

>>> dict = {'key1': {'key2': None}}
>>> print('key2' in dict['key1'])
True
>>> print(dict['key1']['key2'])
None

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM