2

I have the following code, I was wondering if I can convert it to single line for loop?

for a,b in myList :
     sth = calcSth(a, b)
     if sth > 60 :
           return True

return False

another question is: is there any difference in the performance of single line for loop and block-code for loop?

1
  • 1
    Since you added return False at the end: return any(calcSth(a,b)>60 for a,b in myList) Commented Oct 21, 2016 at 19:05

3 Answers 3

5

you can replace your whole loop by this oneliner (is this really a oneliner when using if on a single line?):

if any(calcSth(a,b)>60 for a,b in myList): return True

any will stop testing as soon as a a,b matches the condition.

Also, according to your last edit, if you're planning to return False right after your loop if nothing matches, you can replace the whole routine by:

return any(calcSth(a,b)>60 for a,b in myList)

EDIT: about the performance, I made a quick test, and as predicted, the any construct is roughly 20% faster with the input data I provided (35 items and matching condition in the end, kind of "worst case"). If the matching condition is at the beginning of the list, the difference is very small between both constructions.

Sign up to request clarification or add additional context in comments.

3 Comments

The double parenthesis are not needed: any(calcSth(a, b) ...in myList) is fine syntax. Parenthesis are needed only if the generator is not the only argument to a function call.
return any(x(a,b)>60 for a,b in myList) if he wants to return False if it fails, OP isn't clear
Comments taken into account. Thanks all. @MooingRawr I added the construction you suggest, as-sum-ming that the OP would return False if no computation matches.
1

Maybe something like this (modified):

from itertools import starmap

list(filter(lambda x: x > 60, starmap(calcSth, myList))) != [] 

or, if you don't like to evaluate the full list

from itertools import starmap, islice

list(islice(filter(lambda x: x > 60, starmap(calcSth, myList)), 1)) != []

The last one will stop after the first value that is larger than 60.

4 Comments

This always returns False because a filter object is different from all lists. Only in python2 this can work, but the question is not tagged python2...
you can add the return statement and drop the test against empty list. If not empty, just testing the list will yield True. +1 for the starmap stuff. But I'm not sure that creating a list just to consume the filter is very good for performance.
@Jean-FrançoisFabre Agreed. Looked to me like the OP wanted to get simple objects back. Also agreed on creating the list to consume it is not the best approach. OP wanted a single line.
maybe it would be better to wrap try/except StopIteration around next(filter ...): if there's a least one element, return True. but then no one liner...
0

Strictly speaking, I don't believe there is a single-line equivalent to your posted code. As Jean-Francois answered, you can replace the loop block with a single line, but not the return.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.