How is this evaluated
Steven D'Aprano
steve+comp.lang.python at pearwood.info
Thu Jul 4 21:41:37 EDT 2013
On Thu, 04 Jul 2013 10:20:43 -0700, Arturo B wrote:
> I'm making this exercise: (Python 3.3)
>
> Write a function translate() that will translate a text into
> "rövarspråket" (Swedish for "robber's language"). That is, double every
> consonant and place an occurrence of "o" in between. For example,
> translate("this is fun") should return the string "tothohisos isos
> fofunon".
>
> So I tried to solved it, but I couldn't, so I found many answers, but I
> selected this:
>
> def translate(s):
> consonants = 'bcdfghjklmnpqrstvwxz'
> return ''.join(l + 'o' + l if l in consonants else l for l in s)
The part inside the join(...) is called a generator expression.
I do not recommend generator expressions (or list comprehensions) for
beginners, because they can be confusing until you understand how they
work. As a beginner, if you have a choice between a one-line piece of
code that makes no sense to you, and a five-line piece of code that you
understand, you should choose the one that you understand.
> So I want to question:
> How is the
>
> if 'h' in consonants else 'h' for 'h' in s
>
> part evaluated? (step by step please :P )
That is the wrong question, because you have split the code in the wrong
places. Your generator expression looks like this:
l + 'o' + l if l in consonants else l for l in s
This is a "generator expression" of the form:
(x for l in s)
where x will be defined below. This part is easy enough to understand:
Python will iterate over the string s, extracting one letter at a time l,
and then evaluate the expression "x" below.
What is the expression "x"? It is this part:
(l + 'o' + l if l in consonants else l)
which forms the "ternary operator" if-clause:
value-if-true if condition-being-tested else value-if-false
If you know C, that's like:
?(condition-being-tested, value-if-true, value-if-false)
The condition being tested is, "l in consonants". The value if true is "l
+ 'o' + l". And the value if false is just l.
So putting this all together, we can convert the generator expression
version to this longer, but more readable, version:
def translate(s):
consonants = 'bcdfghjklmnpqrstvwxz'
collector = []
for l in s:
if l in consonants:
collector.append(l + 'o' + l)
else:
collector.append(l)
return ''.join(collector)
--
Steven
More information about the Python-list
mailing list