if the else short form

BartC bc at freeuk.com
Wed Oct 6 10:34:01 EDT 2010


"James Harris" <james.harris.1 at googlemail.com> wrote in message 
news:e8b46ea8-8d1e-4db9-91ba-501fd1a440e7 at g18g2000yqk.googlegroups.com...
> On 29 Sep, 18:20, Seebs <usenet-nos... at seebs.net> wrote:
>> On 2010-09-29, Tracubik <affdfsdfds... at b.com> wrote:
>>
>> > Hi all,
>> > I'm studying PyGTK tutorial and i've found this strange form:
>>
>> > button = gtk.Button(("False,", "True,")[fill==True])
>>
>> > the label of button is True if fill==True, is False otherwise.
>>
>> > i have googled for this form but i haven't found nothing, so can any of
>> > you pass me any reference/link to this particular if/then/else form?
>>
>> Oh, what a nasty idiom.
>>
>> Here's the gimmick.
>>         ("False,", "True,")
>> is a tuple.  That means you can index it.  For instance:
>>         ("False,", "True,")[0]
>> is the string "False,".
>>
>> So, what is the numeric value of "fill == True"?  Apparently, at least
>> at the time this was written, it was 0 if fill was not equal to True,
>> and 1 if fill was equal to True.
>>
>> Let me say, though, that I'm a C programmer, so I'm coming from a 
>> language
>> where the result of 0-or-1 for test operators is guaranteed, and I still
>> wouldn't use this in live code.  It's insufficiently legible.
>
> I'm surprised you don't like this construct. I hadn't seen it until I
> read the OP's question just now. However, it's meaning was immediately
> apparent.
>
> I should say where I'm coming from. Contrast the following C and
> Python:
>
>  text = fill == true ? "True," : "False,";   (C)
>  text = ("False,", "True,")[fill == true]    (Python)

Surely the C should be:  fill ? "True," : "False,";   ?

> I never liked C's ?: construct partly because it doesn't scale well.
> To accept more than two options it requires the programmer to build a
> small hierarchy which can be awful to read and may be best expressed
> as a separate function. I'd rather have a language change a predicate
> to a small integer and use that to index a set of results - and this
> is exactly what the OP's tutorial does.

I use this syntax where there are two possibilities chosen according to 
condition 'a':

(a | b | c)

similar to C's ?: operator. Where there are N possibilities chosen from a 
linear set, I use:

(i | a, b, c, ... |z)      # indexed from 1, default to z

(I think from Algol68 originally.)

The difference from what the Python is doing above, is that only one of the 
possibilities is ever evaluated. Extrapolating the syntax a little, Python I 
think will evaluate all N expressions (maybe even construct the tuple), 
before choosing one.

And I'm not sure there is provision for  a default value either, without 
having a far more complex expression:

x = ("One","Two","Three") [i-1]

While this works for i = 1,2,3, it goes funny for i=0,-1,-2, and generates 
an error for the rest (I'm sure Python has myriad ways of achieving this 
succinctly,  but this isn't it...)

> As another hypothetical example where sgn() returns -1, 0 or +1
>
>  position = ("less", "equal", "greater")[sgn(a - b) + 1]

> Though where the list gets much longer it would be good to be able to
> label the cases for legibility.

You can do, until you want to insert an item in the middle and have to 
re-label everything...

For more complex cases I'd just use a conventional case or switch expression 
which (in my syntax at least), also evaluates just one expression, and 
returns that value. But then you can also start using if-else chains, so 
this is no longer a compact construction useful in an expression.

-- 
Bartc 




More information about the Python-list mailing list