13

Possible Duplicate:
Putting a simple if-then statement on one line

I am working on a python expression and I want that expression to be compressed than using the if else statement.

s = [1, 2, 3, 4]
if len(s)>5:
    print s.index(5)
else:
    print 'cant print'

Is there a better way than using as if else statement?

Community
  • 1
  • 1
sam
  • 18,509
  • 24
  • 83
  • 116
  • 1
    There seems to be a general consensus that an if/else statement _is_ the best way to write it. – Joel Cornett Jul 15 '12 at 13:03
  • I'm just guessing here, but it seems like the intentions of the OP is to avoid the if/elif/case/switch ugliness. Which ultimate solution would be a class-based solution, where the case-selection is done through polymorphism. This can lead to more concise code. – Don Question Jul 15 '12 at 13:12
  • After the latest edit, it seems like the OP only wants to do range checking...? – thebjorn Jul 15 '12 at 13:13
  • yes actually if that index present, then only i want to find that element of that index – sam Jul 15 '12 at 13:17
  • @don: sorry, i tried to ask by simpler way. – sam Jul 15 '12 at 13:21

5 Answers5

17

You can do:

s = [1, 2, 3, 4]
print 'y' if len(s) > 5 else 'n'

However I don't think this makes the code more readable (at a glance). Also note that if and else don't create a loop, they are simply statements for control flow. Loops are written using for and while.

Simeon Visser
  • 118,920
  • 18
  • 185
  • 180
  • 4
    Agreed, this meets OPs request, but doesn't result in more readable code. +1 (reluctantly because of obfuscation) – Levon Jul 15 '12 at 12:39
13

Short, but very obfuscated (don't do this):

print 'ny'[len(s) > 5]

[edit] the reason you should never do this, is because it uses properties of the language that are little known to most people, i.e. that bool is a subclass of int. In most situations where you find yourself writing code like the OP, it's usually better to create a flag variable

s_is_long = len(s) > 5

then you can use any of the more appropriate ways to write the print, e.g.:

print 'y' if s_is_long else 'n'

or

print {True: 'y', False: 'n'}[s_is_long]

or the most readable of all...

if s_is_long:
    print 'y'
else:
    print 'n'
thebjorn
  • 26,297
  • 11
  • 96
  • 138
  • How does that work? Does Python convert the boolean values to integers when indexing? – Simeon Visser Jul 15 '12 at 12:45
  • 3
    While technically correct, this is an awful answer IMO. For many people it will be hard to understand at first glance. Given that the answers to this question will most often be read by people new to the language and/or new to programming in general, I don't think suggesting such constructs is a good idea. – Bryan Oakley Jul 15 '12 at 12:46
  • 1
    Python bools are ints (in the `isinstance` sense -- bool is a subclass of int). – thebjorn Jul 15 '12 at 12:46
  • @Levon: you don't even need `int()`; `True == 1`. – Wooble Jul 15 '12 at 12:47
  • 3
    @Bryan note that I explicitly said "don't do this", so I wouldn't call it a suggestion. – thebjorn Jul 15 '12 at 12:47
  • I really want to upvote this because it's sort of cool to know, but it's really really obfuscated (as the poster notes himself) and error prone code, but therefore won't. Some of the people who'll read this will probably be the least equipped to use it. – Levon Jul 15 '12 at 12:48
  • @thebjorn: Ah okay, booleans are integers in Python. Then it makes sense. – Simeon Visser Jul 15 '12 at 12:48
  • 2
    @thebjorn: while "(don't do this)" is better than nothing, your answer would be better if you spent just a little more effort explaining why someone shouldn't do that. Remember: the audience is mostly people who may not know why that's a bad idea. This is your chance to educate them. – Bryan Oakley Jul 15 '12 at 12:50
7

In this case you could use the try/except block:

try:
    print s.index(5)
except ValueError:
    print "5 not in list"
Don Question
  • 11,227
  • 5
  • 36
  • 54
  • 2
    may i ask why? thats a "pythonic" wy to use it! "Don't ask for permission, but for forgivness!" - Your if-clause is asking for permission and then does what it asked for. the try statment just does it and if it fails it handles the forgivness part. – Don Question Jul 15 '12 at 13:26
  • 1
    Based on OP's comment on the question itself, it seems he actually meant `s[5]` (which would make it an IndexError). But I agree, this is the obviously Pythonic way of spelling range checking. – thebjorn Jul 15 '12 at 13:50
3

Short and clear:

s = [1, 2, 3, 4]
output = {True: 'y',False: 'n'}
print output[len(s) > 5]
zenpoy
  • 19,490
  • 9
  • 60
  • 87
  • Nothing against your solution, but I think the OP's original code is as "short and clear" is it gets when taking readability into account. – Levon Jul 15 '12 at 12:55
  • 1
    You are right, but I've decided to post it as "the right way" of avoiding if-else, instead of counting on some undocumented implicit casting that may get changed over time. – zenpoy Jul 15 '12 at 12:58
  • zenopy's solution is short, clear and is not without elegance ;-) – Don Question Jul 15 '12 at 12:59
  • @zenpoy That is a good reason (and it's certainly clearer than the admittedly clever and cool, but obfuscating code that depends on the values of True/False) – Levon Jul 15 '12 at 13:01
  • @zenpoy while the fact that `bool` is-a `int` might be obscure, it is neither an implicit cast (it's a subtype) nor undocumented (see rationale throughout PEP 285: http://www.python.org/dev/peps/pep-0285/ ). But yes, it definitely is obscure :-) – thebjorn Jul 15 '12 at 13:46
0

Another variation:

print len(s)>5 and 'y' or 'n'

just added for completness. Don't try this at home! ;-)

Don Question
  • 11,227
  • 5
  • 36
  • 54