Check if all numbers in the list match a single icon in Python?

How do I know if a list (or iterable) of numbers has the same sign?

Here is my first (naive) draft:

def all_same_sign(list): negative_count = 0 for x in list: if x < 0: negative_count += 1 return negative_count == 0 or negative_count == len(list) 

Is there a more pythonic and / or correct way to do this? The first thing that comes to mind is to stop the iteration if you have opposite signs.

Update

I like the answers so far, although I'm curious about performance. I am not a performance specialist, but I think it’s wise to consider performance when considering lists. For my particular use case, I don’t think it would be a big problem, but for the sake of completeness of this question, I think it’s good to solve it. I understand that the min and max functions have O (n) performance. The two suggested answers still have O (2n) performance, while my above procedure of adding a short circuit to exit after detecting the opposite sign will have the worst O (n) performance. Thoughts?

+4
source share
4 answers

You can use the all function: -

 >>> x = [1, 2, 3, 4, 5] >>> all(item >= 0 for item in x) or all(item < 0 for item in x) True 

I don't know if this is the most pythonic way.

+16
source

What about:

 same_sign = not min(l) < 0 < max(l) 

Basically, this checks if the smallest element l and the largest element are zero.

This is not a short circuit, but avoids Python loops. Only benchmarking can determine if this is a good compromise for your data (and whether the implementation of this part is important).

+14
source

Instead of all you can use any , since it also closes on the first true element:

 same = lambda s: any(i >= 0 for i in s) ^ any(i < 0 for i in s) 
+3
source

Similar to using all , you can use any , which has the advantage of better performance, since it breaks the loop at the first occurrence of a different sign:

 def all_same_sign(lst): if lst[0] >= 0: return not any(i < 0 for i in lst) else: return not any(i >= 0 for i in lst) 

It would be a little difficult if you want to consider 0 as belonging to both groups:

 def all_same_sign(lst): first = 0 i = 0 while first == 0: first = lst[i] i += 1 if first > 0: return not any(i < 0 for i in lst) else: return not any(i > 0 for i in lst) 

In any case, you repeat the list once, not twice, as in the other answers. Your code has the disadvantage of loop iteration in Python, which is much less efficient than using built-in functions.

+2
source

All Articles