Testing for an empty dictionary in Python

John Machin sjmachin at lexicon.net
Sun Mar 23 21:56:51 EDT 2008


On Mar 24, 11:32 am, Steven D'Aprano <st... at REMOVE-THIS-
cybersource.com.au> wrote:
> On Sun, 23 Mar 2008 10:45:38 -0700, Paul Rubin wrote:
> > John Nagle <na... at animats.com> writes:
> >>    What's the cheapest way to test for an empty dictionary in Python?
>
> >>        if len(dict.keys() > 0) :
>
> > I like to think len(dict) is constant time but I haven't checked the
> > code. Same for bool(dict) (which is what you get when you run "if dict:
> > ...").
>
> Except that "if dict" doesn't needlessly and wastefully create a bool.
>
> >>> from timeit import Timer
> >>> Timer("if {1:2}: pass").timeit()
> 1.1590199184417725
> >>> Timer("if bool({1:2}): pass").timeit()
>
> 1.8825540542602539
>
> Python knows the truth value of built-in types like dicts without
> actually converting them to bools, or for that matter calling __len__ or
> __nonzero__ on them.

What the 2.5.1 interpreter does is call PyObject_IsTrue, which checks
to see if the built_in or extension type is a mapping (not just a
dict) with a length method and if so calls it; similarly for
sequences:

	else if (v->ob_type->tp_as_mapping != NULL &&
		 v->ob_type->tp_as_mapping->mp_length != NULL)
		res = (*v->ob_type->tp_as_mapping->mp_length)(v);
	else if (v->ob_type->tp_as_sequence != NULL &&
		 v->ob_type->tp_as_sequence->sq_length != NULL)
		res = (*v->ob_type->tp_as_sequence->sq_length)(v);

Was that what you meant by "without ... calling __len__"?



More information about the Python-list mailing list