A question of style (finding item in list of tuples)

R

Roy Smith

I've got this code in a django app:

CHOICES = [
('NONE', 'No experience required'),
('SAIL', 'Sailing experience, new to racing'),
('RACE', 'General racing experience'),
('GOOD', 'Experienced racer'),
('ROCK', 'Rock star'),
]

def experience_text(self):
for code, text in self.CHOICES:
if code == self.level:
return text
return "????"

Calling experience_text("ROCK") should return "Rock star". Annoyingly,
django handles this for you automatically inside a form, but if you also
need it in your application code, you have to roll your own.

The above code works, but it occurs to me that I could use the much
shorter:

def experience_text(self):
return dict(CHOICES).get("self.level", "???")

So, the question is, purely as a matter of readability, which would you
find easier to understand when reading some new code? Assume the list
of choices is short enough that the cost of building a temporary dict on
each call is negligible. I'm just after style and readability here.
 
S

Steven D'Aprano

On Mon, 21 May 2012 08:37:29 -0400, Roy Smith wrote:

[...]
The above code works, but it occurs to me that I could use the much
shorter:

def experience_text(self):
return dict(CHOICES).get("self.level", "???")

So, the question is, purely as a matter of readability, which would you
find easier to understand when reading some new code?

Definitely the dictionary lookup.

Rather than convert list CHOICES to a dict every time, you might convert
it to a dict *once*, then just write:

return CHOICES.get(self.level, "???")
Assume the list
of choices is short enough that the cost of building a temporary dict on
each call is negligible.

Negligible or not, why bother?

Not that it really matters -- if you have a good reason for CHOICES to
remain a list, still stick with the dict lookup rather than a explicit
loop.
 
J

Jon Clements

I've got this code in a django app:

CHOICES = [
('NONE', 'No experience required'),
('SAIL', 'Sailing experience, new to racing'),
('RACE', 'General racing experience'),
('GOOD', 'Experienced racer'),
('ROCK', 'Rock star'),
]

def experience_text(self):
for code, text in self.CHOICES:
if code == self.level:
return text
return "????"

Calling experience_text("ROCK") should return "Rock star". Annoyingly,
django handles this for you automatically inside a form, but if you also
need it in your application code, you have to roll your own.

The above code works, but it occurs to me that I could use the much
shorter:

def experience_text(self):
return dict(CHOICES).get("self.level", "???")

So, the question is, purely as a matter of readability, which would you
find easier to understand when reading some new code? Assume the list
of choices is short enough that the cost of building a temporary dict on
each call is negligible. I'm just after style and readability here.

Haven't used django in a while, but doesn't the model provide a get_experience_display() method which you could use...

Failing that, if order isn't important, you can not bother with tuples and have CHOICES be a dict, then pass choices=CHOICES.iteritems() as I believe it takes any iterable, and maybe plug an ordereddict if order is important.

hth

Jon.
 
R

Roy Smith

Haven't used django in a while, but doesn't the model provide a get_experience_display() method which you could use...

Duh, I totally missed seeing that! Yeah, that's exactly what I want. Thanks. Hmmm, looking at the source, I see they went the dict().get() route:

def _get_FIELD_display(self, field):
value = getattr(self, field.attname)
return force_unicode(dict(field.flatchoices).get(value, value), strings_only=True)
 

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,580
Members
45,054
Latest member
TrimKetoBoost

Latest Threads

Top