The pythonic approach

T

Timo Virkkala

def thisReallyWorks(x):
if x == "6$":
return "$10 000"
else:
return x

# or maybe

investments = {"6$": "$10 000"}
def thisReallyWorks(x):
return investments.get(x, x)
 
P

Peter Hansen

Timo said:
def thisReallyWorks(x):
if x == "6$":
return "$10 000"
else:
return x

# or maybe

investments = {"6$": "$10 000"}
def thisReallyWorks(x):
return investments.get(x, x)

I really hope this is a contrived example, because if
I ever saw something like this in real code I'd barf.

Nevertheless, solely for the particular example shown
above, I'd have to say (a) is much better. The (b)
approach is obscure and indirect. One has to pause and
realize that the .get(x, x) thing means that if x
doesn't exist as a key in the dictionary, it will
instead be returned as the actual result. Using
x as the input, the lookup key, and the default result
makes the whole thing look bizarre and ill-conceived.

(My gut tells me that if this were something that was
required in real code, it would actually be using an
existing dictionary (not one created with a single
entry just before the function) and the best code
would be an inline .get() rather than a function call,
and that x might not even be its own default, but
I can't imagine what real code this corresponds to
so that's all I have to say about that. :)

-Peter
 
T

Timo Virkkala

Peter said:
I really hope this is a contrived example, because if
I ever saw something like this in real code I'd barf.
[snip]

It was, very contrived. I just like writing (wannabe) funny replies to
spams... :) The idea in the second one was to be extensible. Yes, the dict
should be defined elsewhere, and yes, inline .get is (usually) better than
hiding it in a function.

Maybe I should just write real code and not bother with nonsense :)
 
S

Steven Bethard

Peter Hansen said:
(My gut tells me that if this were something that was
required in real code, it would actually be using an
existing dictionary (not one created with a single
entry just before the function) and the best code
would be an inline .get() rather than a function call,
and that x might not even be its own default, but
I can't imagine what real code this corresponds to
so that's all I have to say about that.

I actually wrote code not too long ago that did make a call like .get(x, x).
I had a dictionary of word stems, e.g.
{"invention":"invent", "assistance":"assist", ...} read in from a file. For
the particular app, if there was no stem for a word, I wanted to get the word
back. I didn't have a function for it in my code, but I don't see why a
function like:

def getstem(self, word):
return self.stemdict.get(word, word)

would be so unreasonable.

I don't know why you would have to "pause to realize" that .get(x, x) returns
x as the default any more than you'd have to "pause to realize" that .get(x,
y) returns y as the default...

Steve
 
P

Peter Hansen

Steven said:
I actually wrote code not too long ago that did make a call like .get(x, x).
I had a dictionary of word stems, e.g.
{"invention":"invent", "assistance":"assist", ...} read in from a file. For
the particular app, if there was no stem for a word, I wanted to get the word
back. I didn't have a function for it in my code, but I don't see why a
function like:

def getstem(self, word):
return self.stemdict.get(word, word)

would be so unreasonable.

It wouldn't be "so unreasonable". Furthermore, it's a valid
example with context that makes it understandable and therefore
easier to discuss. I also point out that it uses a dictionary
with much more in it than one item... And the function name
makes sense in the problem domain, helping one understand the
purpose of the function and, thus, the reason for that particular
code pattern. (Even so, I would tend to include a doc-string
or comment describing the basic algorithm, to let another
programmer more easily comprehend the approach taken.)
I don't know why you would have to "pause to realize" that .get(x, x) returns
x as the default any more than you'd have to "pause to realize" that .get(x,
y) returns y as the default...

Principle of least surprise. One rarely encounters .get(x, x)
and so, upon seeing it, at least in the context of the contrived
example (as opposed to in your own example), one might at first
think it was a mistake.

Personally, I'd use a regular lookup and catch the KeyError,
making it very explicit what the intent of the author was.
And that's the subject of the thread, after all: what is
the more pythonic approach. For me, it's the one that
leads to the least surprise and potential for confusion.
(For others, it quickly gets into discussions of which
approach is "faster", as we may shortly see. ;-)

-Peter
 
A

Alex Martelli

Steven Bethard said:
I actually wrote code not too long ago that did make a call like .get(x, x).

I consider somedict.get(x, x) a _frequent_ Python idiom!

translate_some_tags = dict(
application='literal',
foobar='barfoo',
whatever='somethingelse',
}

def translate_tag(tagName, attributes_dict):
if tagName == 'emphasis' and attributes.get('role')=='bold':
return 'bold'
else:
return translate_some_tags.get(tagName, tagName)

Isn't that a pretty frequent idiom when doing some minor massaging of
XML markup, for example? (Spare me the passionate defenses of XSLT
please... I'm happy to use XSLT when warranted, but a lot of the XML
processing I do, and I _do_ do a lot of that, is in
Python+pulldom...!-).
back. I didn't have a function for it in my code, but I don't see why a
function like:

def getstem(self, word):
return self.stemdict.get(word, word)

would be so unreasonable.

A very good idea! If tomorrow you need to specialcase something, based
e.g. on RE's, you stick those into getstem (just like I do in
translate_tag for the few cases where a tag's translation may depend on
its attributes), and Bob's your uncle. MUCH better than spreading calls
to get(word,word) all over the place!!!


Alex
 
A

Alex Martelli

Peter Hansen said:
code pattern. (Even so, I would tend to include a doc-string
or comment describing the basic algorithm, to let another
programmer more easily comprehend the approach taken.)

That's never wrong, of course.
Principle of least surprise. One rarely encounters .get(x, x)

Funny -- I encounter it SO often I consider it a basic idiom!!!


Alex
 
P

Peter Hansen

Alex said:
Funny -- I encounter it SO often I consider it a basic idiom!!!

I think if the example had been one like your XML massaging
example, it wouldn't have felt very out of place, even if
I haven't seen it very often. (I'm quite sure I've used
it myself, for the same "optional translation" characteristics,
but I guess I work in areas different enough that it hasn't
been frequent.)

-Peter
 

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,579
Members
45,053
Latest member
BrodieSola

Latest Threads

Top