dict.has_key(x) versus 'x in dict'

M

Marc 'BlackJack' Rintsch

My point was really that there is no obvious implementation for 'in' on
dictionaries, so it should have been left out. And that GvR thought so
for quite some time as well (until he got mixed up with a crowd of ex
C++ programmers).

Maybe there's no obvious implementation for ``in`` and dictionaries but
there is the semantics of ``in`` and iterables. Dictionaries are iterable
so it's clearly defined what ``'answer' in {'answer': 42}`` should return.

In [84]: class A:
....: def __iter__(self):
....: return iter((1,2,3))
....:

In [85]: a = A()

In [86]: 2 in a
Out[86]: True

In [87]: 5 in a
Out[87]: False

If ``in`` shouldn't work with dictionaries, either `__contains__()` must
be implemented to throw an exception or dictionaries shouldn't be iterable.

Ciao,
Marc 'BlackJack' Rintsch
 
D

Daniel Dittmar

Marc said:
If ``in`` shouldn't work with dictionaries, either `__contains__()` must
be implemented to throw an exception or dictionaries shouldn't be iterable.

I agree completely (in the sense that dictionaries shouldn't be iterable
directly). Probably even more strongly, at least every time I see some
code where someone iterates over the keys, only to use the key to look
up the value (instead if using iteritms).

For strings, the 1:1 relationship between 'in' and iteration has already
been broken. But then, iteration over strings happens in my code only
when a pass a string where I should have passed a list of strings.

Daniel
 
F

Fredrik Lundh

Daniel said:
I agree completely (in the sense that dictionaries shouldn't be iterable
directly). Probably even more strongly, at least every time I see some
code where someone iterates over the keys, only to use the key to look
up the value (instead if using iteritms).

so? that's the original Python way of doing things, and is both very
readable and surprisingly efficient:

$ timeit -s "d = vars()" "for k in d: v = d[k]"
1000000 loops, best of 3: 0.472 usec per loop

$ timeit -s "d = vars()" "for k, v in d.iteritems(): pass"
1000000 loops, best of 3: 0.663 usec per loop

</F>
 
S

Stephen Eilert

Ben Finney escreveu:
They're only not-so-obvious to those who learn one version of Python
and then ignore release notes on future versions. The "k in some_dict"
was a wonderful thing to read in the release notes, and I was glad
enough that I never forgot it :)

Hmm, that sounds rather snarky. I guess I'm only saying that one's
duty to oneself as a programmer is to keep up with the improved idioms
as they appear in new releases of one's language of choice.

That's fine.

I do need to read those release notes retroactively, though.


Stephen
 
H

Hendrik van Rooyen

Hendrik van Rooyen schreef:

Have you never experienced the following:

A customer reports a bug. Upon investaging you find the source of the
problem, but from studying the code you don't understand anymore how it
has ever been able to function correctly. From that moment, it indeed
stops working even on computers where it always have worked correctly.

You fix the bug and all is well again.

Very strange, but it has happened to me on a few occasions. There's
probably a perfectly logical explanation for what happened, but I never
found it.

This is simply a manifestation of the faith that can move mountains - while
everybody believed that it was working, it did, and stopped working only because
of the heretical doubt of some infidel...

:) - Hendrik
 
S

Steven D'Aprano

I agree completely (in the sense that dictionaries shouldn't be iterable
directly).

Why on earth not???

Probably even more strongly, at least every time I see some
code where someone iterates over the keys, only to use the key to look
up the value (instead if using iteritms).

Is there really that much difference between the two?
.... for key in D:
.... value = D[key]
........ for key, value in D.iteritems():
.... pass
....4.7772250175476074

Using iteritems is slightly faster, and probably more Pythonic, but the
difference isn't so great to argue that "for key in dict" is always the
wrong thing to do.

One could argue until the cows come home whether "for x in dict" should
iterate over keys, values or key/value pairs, but it really doesn't
matter. All three possibilities are available, all three values are
useful, and having to copy the keys/values into a list in order to iterate
over them is just wasteful.
 
S

skip

Hendrik> - as long as it works, and is fast enough, its not broken, so
Hendrik> don't fix it...

Hendrik> LOL - this is kind of weird - it was working, nobody
Hendrik> complained, you fiddled with it to make it faster, (just
Hendrik> because you could, not because you had to, or were asked to),
Hendrik> it became faster, and then, suddenly, retrospectively, it
Hendrik> became a problem ????

No, I think you misunderstand. I was poking around in that function for
other reasons, saw the "k in d.keys()" and realized that the wrong way to
write it. Rewrote it and noticed the performance increase. What's so weird
about that?

Skip
 
H

Hendrik van Rooyen

Hendrik> - as long as it works, and is fast enough, its not broken, so
Hendrik> don't fix it...


Hendrik> LOL - this is kind of weird - it was working, nobody
Hendrik> complained, you fiddled with it to make it faster, (just
Hendrik> because you could, not because you had to, or were asked to),
Hendrik> it became faster, and then, suddenly, retrospectively, it
Hendrik> became a problem ????

No, I think you misunderstand. I was poking around in that function for
other reasons, saw the "k in d.keys()" and realized that the wrong way to
write it. Rewrote it and noticed the performance increase. What's so weird
about that?

Nothing wrong with that - it is meet and good to make improvements as you spot
them - what seemed weird to me was not that you made the change, but that you
described it as a problem, retrospectively - why I say this, I expect, is that
in my
mind, such a definition would list as a "problem" all working code that could,
by rummaging around in it, be improved in some way.

I suspect that such a definition would condemn almost *all* production code to
problem status...

I just don't see it that way - my attitude, I suppose, is a wimpy one, as I
think that working code in production use should be left alone, as every
time you touch it, there is a finite non zero probability that you will do
something stupid to break it, and the breakage may be subtle, and
undiscovered for a while, and then it will really be a problem...

So the weirdness for me was that you called a piece of perfectly good working
code a problem, just because it was faster after you fixed it, even though you
had no prior knowledge of the offending line that was doing the right thing,
albeit slowly. - I would only have called such a piece of code a problem if I
had been inundated with prior requests to fix the slow-running dog...

I dunno if all this makes any sense - and we are getting way off topic. :)

- Hendrik
 

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

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,581
Members
45,055
Latest member
SlimSparkKetoACVReview

Latest Threads

Top