foresightyj
foresightyj

Reputation: 2106

dict.has_key(somekey) does not work equally as somekey in dict

I recently encountered a weird problem with python dictionary while playing with Beautifulsoup. My code looks like this.

import urllib2
from BeautifulSoup import BeautifulSoup

response = urllib2.urlopen("http://www.msn.com")
html = response.read()
soup = BeautifulSoup(html)
anchors = soup.findAll('a')
for a in anchors:
    if not a.has_key('href') == 'href' in a:
        print a

It actually printed out a lot of links, in which has_key works differently as 'in'.

Can anybody explain Thanks a lot!

Upvotes: 0

Views: 1123

Answers (2)

kunev
kunev

Reputation: 63

This comes from the precedence of operators:

>>> a = {'a': 5, 'b': 6}
>>> a.has_key('a')
True
>>> 'a' in a
True
>>> a.has_key('a') == 'a' in a
False
>>> a.has_key('a') == ('a' in a)
True
>>> (a.has_key('a') == 'a') in a
False

So in your case

if not a.has_key('href') == 'href' in a:
        print a

actually means

if not (a.has_key('href') == 'href') in a:
        print a

while you want to chech

if not a.has_key('href') == ('href' in a):
        print a

Furthermore the thing with deprecating has_key and not supporting it in python3. If you have a choice, dump python2 all together and go for 3.x

Upvotes: 1

Nicolas
Nicolas

Reputation: 5678

You probably want:

if not a.has_key('href'):

Or a much Pythonic way of checking this:

if 'href' not in a:

has_key() works like the in keyword (as the other answers pointed out, you forgot parenthesis) but has_key() is deprecated and not supported in Python 3.x. So you should always use in.

Upvotes: 4

Related Questions