Way for see if dict has a key

M

Michele Petrazzo

Hi ng,
what the preferred way for see if the dict has a key?
We have a lot of solutions:

key in dict
key in dict.keys()
dict.has_key(key)
....

but what the better or the more "pythonic"?

Thanks,
Michele
 
C

Chance Ginger

Hi ng,
what the preferred way for see if the dict has a key?
We have a lot of solutions:

key in dict
key in dict.keys()
dict.has_key(key)
...

but what the better or the more "pythonic"?

Thanks,
Michele

It is a religious call....
 
M

Michele Petrazzo

Fredrik said:
new syntax (2.3 and later).

So, following it, it can be used for the operations like len?

len(dict) -> len(dict.keys()) ?

Thanks,
Michele
 
B

Bruno Desthuilliers

Michele said:
Hi ng,
what the preferred way for see if the dict has a key?
We have a lot of solutions:

key in dict
key in dict.keys()
dict.has_key(key)
...

try:
dict[key]
except KeyError:
...
else:
...
but what the better

Depends on the context.
 
?

=?iso-8859-1?B?QW5kcuk=?=

Michele said:
If know only one context: see if the key are into the dict... What other
context do you know?

Michele

Perhaps Bruno meant this:

try:
... my_dict[key] ...
except:
....

when we expect that the key will most often be in my_dict so that
exception will be raised rarely, otherwise use

if key in dict

André
 
M

Michele Petrazzo

André said:
Michele said:
If know only one context: see if the key are into the dict... What other
context do you know?

Michele

Perhaps Bruno meant this:

try:
... my_dict[key] ...
except:
....

Yes I see :)
when we expect that the key will most often be in my_dict so that
exception will be raised rarely

I didn't thought this because if I think that a key aren't in a dict, I
use dict.get(key, default)
otherwise use if key in dict

André

Thanks to all,
Michele
 
F

Fredrik Lundh

André said:
Perhaps Bruno meant this:

try:
... my_dict[key] ...
except:
...

when we expect that the key will most often be in my_dict so that
exception will be raised rarely, otherwise use

on my machine, "key in dict" is about twice as fast as the full try/getitem con-
struct when the key is present in the dict, so that's not a very good optimization.

now, if the OP had been interested in the associated value, things might have
been a bit different.

</F>
 
L

looping

Michele said:
If know only one context: see if the key are into the dict... What other
context do you know?

Michele

Why do you want to do that ?

if key in dict:
value = dict[key]
else:
value = None

could be write:

try:
value = dict[key]
except KeyError:
value = None

so depends of the context...
 
F

Fredrik Lundh

Michele said:
It, is the thought that the new 2.3 introduce.

support for "key in dictionary" form was added in 2.3 (in earlier versions,
"in" was only supported for sequences, not for mappings).

len(dictionary) works in all Python versions.

</F>
 
B

Bruno Desthuilliers

looping said:
Michele said:
If know only one context: see if the key are into the dict... What other
context do you know?

Why do you want to do that ?

if key in dict:
value = dict[key]
else:
value = None

could be write:

value = dict.get(key, None)

(snip)
 
B

Bruno Desthuilliers

Fredrik said:
:

Perhaps Bruno meant this:

try:
... my_dict[key] ...
except:
...

when we expect that the key will most often be in my_dict so that
exception will be raised rarely, otherwise use


on my machine, "key in dict" is about twice as fast as the full try/getitem con-
struct when the key is present in the dict,

Doesn't it depends on the number of keys in the dict ?
so that's not a very good optimization.

FWIW, I personaly didn't meant to present it as an optimisation - just
as one more possible way to test the existence of a given key...
 
P

Paul McGuire

Michele Petrazzo said:
I didn't thought this because if I think that a key aren't in a dict, I
use dict.get(key, default)

Another factor to consider is if "default" is not something simple like 0 or
None, but is an object constructed and initialized with some expensive
initialization code (like access to a database). In this case:

dict.get(key, ExpensiveObjectToCreate())

always creates the default value, and if the key does not exist, then
promptly drops it on the floor.

In such a case you'd be better off with one of the "check for existence"
patterns, which only creates the default value if you *know* you're going to
need it.

-- Paul
 
G

Georg Brandl

Bruno said:
looping said:
Michele said:
Bruno Desthuilliers wrote:

but what the better

Depends on the context.


If know only one context: see if the key are into the dict... What other
context do you know?

Why do you want to do that ?

if key in dict:
value = dict[key]
else:
value = None

could be write:

value = dict.get(key, None)

value = dict.get(key)

;)

Georg
 
F

Fredrik Lundh

Paul McGuire wrote:

Another factor to consider is if "default" is not something simple like 0 or
None, but is an object constructed and initialized with some expensive
initialization code (like access to a database). In this case:

dict.get(key, ExpensiveObjectToCreate())

always creates the default value, and if the key does not exist, then
promptly drops it on the floor.

In such a case you'd be better off with one of the "check for existence"
patterns, which only creates the default value if you *know* you're going to
need it.

unless you're targeting 2.5 or later, in which case you can use the
defaultdict class:
.... print "creating an expensive object"
.... return "expensive object"
....
>>> d = collections.defaultdict(ExpensiveObjectToCreate)
>>> d["key"]
creating an expensive object
'expensive object'
'expensive object'

or, if you prefer, the new __missing__ hook:
.... def __missing__(self, key):
.... print "add new object base on", key
.... value = "new object"
.... self[key] = value
.... return value
....
add new object base on key
'new object'
'new object'

</F>
 
B

Bruno Desthuilliers

Fredrik said:
why would it depend on the number of keys in the dict ?

</F>

Seems that if "key in dict" do a simple linear search, it depends on the
number of keys in dict (and the position of the searched key etc...).

And if I'm missing the point and you it and you know why, it would be
simple to explain than to answer my question with another question.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
474,262
Messages
2,571,059
Members
48,769
Latest member
Clifft

Latest Threads

Top