Can I use a conditional in a variable declaration?

Discussion in 'Python' started by volcs0@gmail.com, Mar 19, 2006.

  1. Guest

    I've done this in Scheme, but I'm not sure I can in Python.

    I want the equivalent of this:

    if a == "yes":
    answer = "go ahead"
    else:
    answer = "stop"

    in this more compact form:


    a = (if a == "yes": "go ahead": "stop")


    is there such a form in Python? I tried playing around with lambda
    expressions, but I couldn't quite get it to work right.
     
    , Mar 19, 2006
    #1
    1. Advertising

  2. Kent Johnson Guest

    wrote:
    > I want the equivalent of this:
    >
    > if a == "yes":
    > answer = "go ahead"
    > else:
    > answer = "stop"
    >
    > in this more compact form:
    >
    >
    > a = (if a == "yes": "go ahead": "stop")


    If the value for the 'true' case can never have a boolean value of
    False, you can use this form:

    a = (a == "yes") and "go ahead" or "stop"

    The short-circuit evaluation of 'and' and 'or' give the correct result.
    This will not work correctly because the 'and' will always evaluate to
    "" which is False so the last term will be evaluated and returned:

    a = (a == "yes") and "" or "stop"

    and IMO the extra syntax needed to fix it isn't worth the trouble; just
    spell out the if / else.

    Kent
     
    Kent Johnson, Mar 19, 2006
    #2
    1. Advertising

  3. wrote:
    > I've done this in Scheme, but I'm not sure I can in Python.
    >
    > I want the equivalent of this:
    >
    > if a == "yes":
    > answer = "go ahead"
    > else:
    > answer = "stop"
    >
    > in this more compact form:
    >
    >
    > a = (if a == "yes": "go ahead": "stop")
    >
    >
    > is there such a form in Python? I tried playing around with lambda
    > expressions, but I couldn't quite get it to work right.


    There will be, in Python 2.5 (final release scheduled for August 2006):

    >>> answer = "go ahead" if a=="yes" else "stop"


    See:
    http://mail.python.org/pipermail/python-dev/2005-September/056846.html
    http://www.python.org/doc/peps/pep-0308/

    --Ben
     
    Ben Cartwright, Mar 19, 2006
    #3
  4. Guest

    Kent - Thanks for the quick reply. I tried the and/or trick - it does
    work. But you're right - more trouble than its worth.... So for now, I
    did it "the long way". It looks like (see below), this functionality
    will be added in soon.

    Thanks for the quick help.

    -sam
     
    , Mar 19, 2006
    #4
  5. Paul Rubin Guest

    writes:
    > a = (if a == "yes": "go ahead": "stop")
    >
    > is there such a form in Python? I tried playing around with lambda
    > expressions, but I couldn't quite get it to work right.


    This has been the subject of huge debate over the years. The answer
    is Python doesn't currently have it, but it will be added to a coming
    version: See http://www.python.org/doc/peps/pep-0308/

    To do it in the most general way with lambda expressions, use (untested):

    a = (lambda: iffalse_expression,
    lambda: iftrue_expression)[bool(condition)]()

    That makes sure that only one of the target expressions gets evaluated
    (they might have side effects).

    There are various more common idioms like

    a = (condition and iftrue_expression) or iffalse_expression

    which can go wrong and evaluate both expressions. It was a bug caused
    by something like this that led to conditional expressions finally
    being accepted into Python.
     
    Paul Rubin, Mar 19, 2006
    #5
  6. On 2006-03-19, <> wrote:

    > I want the equivalent of this:
    >
    > if a == "yes":
    > answer = "go ahead"
    > else:
    > answer = "stop"


    If that's what you want, then write that. ;)

    --

    Grant Edwards
     
    Grant Edwards, Mar 19, 2006
    #6
  7. wrote:

    > I want the equivalent of this:
    >
    > if a == "yes":
    > answer = "go ahead"
    > else:
    > answer = "stop"
    >
    > in this more compact form:
    >
    > a = (if a == "yes": "go ahead": "stop")
    >
    > is there such a form in Python? I tried playing around with lambda
    > expressions, but I couldn't quite get it to work right.


    Rather than lambda, this merits a named function. You only have to
    define it once.

    def mux(s, t, f):
    if s:
    return t
    return f

    def interpret(a):
    answer = mux(a == "yes", "go ahead", "stop")
    print answer

    interpret("yes") # Prints "go ahead."
    interpret("no") # Prints "stop."
     
    Jeffrey Schwab, Mar 19, 2006
    #7
  8. Ron Adam Guest

    wrote:
    > I've done this in Scheme, but I'm not sure I can in Python.
    >
    > I want the equivalent of this:
    >
    > if a == "yes":
    > answer = "go ahead"
    > else:
    > answer = "stop"
    >
    > in this more compact form:
    >
    >
    > a = (if a == "yes": "go ahead": "stop")
    >
    >
    > is there such a form in Python? I tried playing around with lambda
    > expressions, but I couldn't quite get it to work right.



    I sometimes find it useful to do:


    answers = {True: "go ahead", False: "stop"}

    answer = answers[a == "yes"]



    This is also sometimes useful when you want to alternate between two values.

    values = {'a':'b', 'b':'a'} # define outside loop

    while 1:
    v = values[v] # alternate between 'a' and 'b'
    ...

    There are limits to this, both the keys and the values need to be hashable.


    Cheers,
    Ron
     
    Ron Adam, Mar 19, 2006
    #8
  9. Georg Brandl Guest

    Jeffrey Schwab wrote:
    > wrote:
    >
    >> I want the equivalent of this:
    >>
    >> if a == "yes":
    >> answer = "go ahead"
    >> else:
    >> answer = "stop"
    >>
    >> in this more compact form:
    >>
    >> a = (if a == "yes": "go ahead": "stop")
    >>
    >> is there such a form in Python? I tried playing around with lambda
    >> expressions, but I couldn't quite get it to work right.

    >
    > Rather than lambda, this merits a named function. You only have to
    > define it once.
    >
    > def mux(s, t, f):
    > if s:
    > return t
    > return f


    But be aware that this is not a complete replacement for a syntactic
    construct. With that function, Python will always evaluate all three
    arguments, in contrast to the and/or-form or the Python 2.5 conditional.

    You can show this with

    test = mux(False, 1/0, 1)

    and

    test = False and 1/0 or 1

    Georg
     
    Georg Brandl, Mar 19, 2006
    #9
  10. andy Guest

    wrote:

    >I've done this in Scheme, but I'm not sure I can in Python.
    >
    >I want the equivalent of this:
    >
    >if a == "yes":
    > answer = "go ahead"
    >else:
    > answer = "stop"
    >
    >in this more compact form:
    >
    >
    >a = (if a == "yes": "go ahead": "stop")
    >
    >
    >is there such a form in Python? I tried playing around with lambda
    >expressions, but I couldn't quite get it to work right.
    >
    >
    >

    How about:

    a = ["stop","go ahead"][a == "yes"]

    This works because:

    >>> int("yes" == "yes")

    1
    >>> int("yes" == "no")

    0

    Taking into account all the previous comments - both the literal list
    elements are evaluated; there is no short-cirtuiting here. If they're
    just literals, it's no problem, but if they're (possibly
    compute-intensive) function calls, it would matter. I find the list
    evaluation easier to parse than the and/or equation, and in instances
    where that would be necessary, I will use the longhand if ... else ...
    structure for readability.

    hth,
    -andy
     
    andy, Mar 19, 2006
    #10
  11. Georg Brandl wrote:
    > Jeffrey Schwab wrote:
    >> wrote:
    >>
    >>> I want the equivalent of this:
    >>>
    >>> if a == "yes":
    >>> answer = "go ahead"
    >>> else:
    >>> answer = "stop"
    >>>

    >> def mux(s, t, f):
    >> if s:
    >> return t
    >> return f

    >
    > But be aware that this is not a complete replacement for a syntactic
    > construct. With that function, Python will always evaluate all three
    > arguments, in contrast to the and/or-form or the Python 2.5 conditional.


    Absolutely true, and I should have mentioned it. In languages that
    allow ?: syntax, I rarely rely on its short-circuit effect, but it
    certainly is a significant difference.
     
    Jeffrey Schwab, Mar 19, 2006
    #11
  12. Ron Adam <> wrote:
    > wrote:
    >> I want the equivalent of this:
    >>
    >> if a == "yes":
    >> answer = "go ahead"
    >> else:
    >> answer = "stop"
    >>
    >> in [a] more compact form:

    >I sometimes find it useful to do:
    >
    > answers = {True: "go ahead", False: "stop"}
    > answer = answers[a == "yes"]


    In this particular case, you can get it even more compact as

    answer = {"yes": "go ahead"}.get(a, "stop")

    but that's sacrificing elegance and readability for bytes. When I find
    myself with code like the OP's, I usually rewrite as:

    answer = "stop"
    if a == "yes":
    answer = "go ahead"

    --
    \S -- -- http://www.chaos.org.uk/~sion/
    ___ | "Frankly I have no feelings towards penguins one way or the other"
    \X/ | -- Arthur C. Clarke
    her nu becomeþ se bera eadward ofdun hlæddre heafdes bæce bump bump bump
     
    Sion Arrowsmith, Mar 21, 2006
    #12
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Willem Oosthuizen

    Conditional signal declaration

    Willem Oosthuizen, Jul 16, 2003, in forum: VHDL
    Replies:
    5
    Views:
    7,039
    Mario Trams
    Jul 17, 2003
  2. Alec S.
    Replies:
    10
    Views:
    10,325
    Alec S.
    Apr 16, 2005
  3. Replies:
    4
    Views:
    1,133
    Richard Tobin
    Dec 12, 2006
  4. Bolin
    Replies:
    4
    Views:
    421
  5. Nicolas Matringe
    Replies:
    5
    Views:
    7,834
    Nicolas Matringe
    Apr 19, 2007
Loading...

Share This Page