how to do this function in one line

Is it possible to do this code in one line. I tried it with a lambda funcion and python for loop one liner and Im not able to do it. The problem in for one liner is to make the break point in the loop, returning True.

self.exists = False
for value in self.dict_times.values():
    if value!= 0: 
        self.exists = True
        break

Upvotes: 1

Views: 106

Answers (4)

Thank you Paul M. This one works perfect.

self.exists = any(value != 0 for value in self.dict_items.values())

Upvotes: 0

gboffi
gboffi

Reputation: 25023

TL;DR any(1 for val in values if val != 0)


As many have already told you, both in comments and answers, any() is the way to go.

any doc string says

In [13]: any?
Signature: any(iterable, /)
Docstring:
Return True if bool(x) is True for any x in the iterable.

If the iterable is empty, return False.
Type:      builtin_function_or_method

but it fails to mention that any is a short-circuit operator, that stops the iteration as soon as one of the tests evaluates to true, so that your requirement about breaking the loop is satisfied by any.

Let's check that for a sequence of 0 and 1 any does the right thing

In [14]: any((0,0,1,0,1))
Out[14]: True

instead of a sequence the argument of any can be also a generator, this helps us to show that we have a short circuiting indeed

In [15]: any((print(val) or val) for val in (0,0,1,0,1))
0
0
1
Out[15]: True

as you can see, the last print that is evaluated is associated with the first one and we skip the last two items in (0,0,1,0,1).

Now, what happens if we interpret strictly your test value != 0 ?

In [16]: any((print(val) or val) for val in (0,0,None,0,0))
0
0
None
0
0
Out[16]: False

In [17]: None != 0
Out[17]: True

So, if we are serious about value != 0, we have to write

In [18]: any(1 for val in (0,0,None,0,0) if (print(val) or val) != 0)
0
0
None
Out[18]: True

What happens if your sequence contains a boolean? to answer, let's see the results of the test

In [19]: False != 0, True != 0
Out[19]: (False, True)

In [20]: any(1 for val in (0,False) if (print(val) or val) != 0)
0
False
Out[20]: False

So, if we want to stay with Python semantics, that's it, if we want to stress the fact that False is not zero, well, there is the is not logical test that in this specific case (checking with zero) works because in CPython at least (the most common interpreter) small integers are cached

In [21]: any(1 for val in (0,False) if (print(val) or val) is not 0)
<>:1: SyntaxWarning: "is not" with a literal. Did you mean "!="?
<ipython-input-21-062bcd4ba4c9>:1: SyntaxWarning: "is not" with a literal. Did you mean "!="?
  any(1 for val in (0,False) if (print(val) or val) is not 0)
0
False
Out[21]: True

so, it works but we have that nasty SyntaxWarning ... but it's easy to fix

In [22]: z = 0

In [23]: any(1 for val in (0,False) if (print(val) or val) is not z)
0
False
Out[23]: True

but probably this last expression is overdone.

Upvotes: 1

Ben
Ben

Reputation: 92

Yes.
self.exists = bool(sum(self.dict_times.values()))

Upvotes: 0

wasif
wasif

Reputation: 15488

Yeah, use any():

self.exists = any(self.dict_times.values())

Upvotes: 5

Related Questions