1

I keep having to do this operation all over the place in my python code. I'm willing to bet there is an easier (aka one-line) way to do this.

results = getResults()
if len(results) > 0:
    result = results[0]

I actually don't need "results" anywhere else, and I should only run "getResults" once.

Any ideas?

Joe Hillenbrand
  • 845
  • 9
  • 26
  • Be aware also that in the recommended Python style guidelines ( [PEP 8](http://www.python.org/dev/peps/pep-0008/)), the method should be named `get_results` rather than `getResults`. – Chris Morgan Nov 21 '10 at 11:27

5 Answers5

8

You haven't specified what result should be if results is empty, but this is one option (assuming Python 2.6 or greater):

result = results[0] if results else None
Alec Thomas
  • 19,639
  • 4
  • 30
  • 24
2

result = len(results) and results[0] or None. In case if results[0] is not 0, or False, or any empty container [], (), '', {}, set(), ....

khachik
  • 28,112
  • 9
  • 59
  • 94
  • I think you should make it clearer that this will _only_ work if `results[0]` evaluates to `True`. If `results == range(10)`, say, it will give None. – Katriel Nov 21 '10 at 12:42
  • @katrielex my comment (the second sentence in the post) doesn't make it clear? – khachik Nov 21 '10 at 13:05
  • @khachik: no. _Any_ empty container evaluates to False -- `set()`, `tuple()`, `{}`, `frozenset()`, `0.0`, ... -- it will fail for _any_ of these. – Katriel Nov 21 '10 at 13:17
  • @khachik: closer =) but still unfortunately not true... a) `0j`, `0L`, `0.0` and b) any class can define a `__nonzero__` method which returns False, in which case instances of that class will evaluate to False. The point is that _anything_ which evaluates to False will cause fail. [Although now I'm just nitpicking; these are at best unlikely to come up.] – Katriel Nov 21 '10 at 13:23
  • @katrielalex I understand that point, thanks :) also there is `__bool__` in 3.x, there is None... Isn't it obvious since `and` is used? – khachik Nov 21 '10 at 13:40
  • @khachik: yes, I guess so. I think the answer is fine, I'm just nitpicking. =) – Katriel Nov 21 '10 at 13:42
1

next(iter(getResults()), None) for Python 2.6

Rosh Oxymoron
  • 20,355
  • 6
  • 41
  • 43
0

If you don't actually need results anywhere, consider a function that returns just the first result, and use that instead.

def getFirstResult():
    results = getResults()
    if len(results) > 0:
        return results[0]
    else:
        return None
grifaton
  • 3,986
  • 4
  • 30
  • 42
0

If you can change getResults() slightly along these lines:

def getResults():
    # ...
    getResults.seq = ... # save results in a func attribute
    return getResults.seq

It would allow you to write:

results = getResults.seq[0] if getResults() else None
martineau
  • 119,623
  • 25
  • 170
  • 301
  • getResults is just an example. It would actually be a different function whenever I use it, and I don't want to have to write a wrapper for every time I use it. – Joe Hillenbrand Nov 21 '10 at 11:50
  • @Joehillen: This isn't a wrapper, it a permanent change to the function itself that is backwards compatible with previous usage but also allows the one-liner example usage to be used when desired. It's also possible to do it without modifying the function -- see the question [pythonic way to rewrite an assignment in an if statement](http://stackoverflow.com/questions/3744382/pythonic-way-to-rewrite-an-assignment-in-an-if-statement). – martineau Nov 21 '10 at 12:05