How to count the number of occurrences of `None` in a list?
Question:
I’m trying to count things that are not None
, but I want False
and numeric zeros to be accepted too. Reversed logic: I want to count everything except what it’s been explicitly declared as None
.
Example
Just the 5th element it’s not included in the count:
>>> list = ['hey', 'what', 0, False, None, 14]
>>> print(magic_count(list))
5
I know this isn’t Python normal behavior, but how can I override Python’s behavior?
What I’ve tried
So far I founded people suggesting that a if a is not None else "too bad"
, but it does not work.
I’ve also tried isinstance
, but with no luck.
Answers:
Just use sum
checking if each object is not None
which will be True
or False
so 1 or 0.
lst = ['hey','what',0,False,None,14]
print(sum(x is not None for x in lst))
Or using filter
with python2:
print(len(filter(lambda x: x is not None, lst))) # py3 -> tuple(filter(lambda x: x is not None, lst))
With python3 there is None.__ne__()
which will only ignore None’s and filter without the need for a lambda.
sum(1 for _ in filter(None.__ne__, lst))
The advantage of sum
is it lazily evaluates an element at a time instead of creating a full list of values.
On a side note avoid using list
as a variable name as it shadows the python list
.
lst = ['hey','what',0,False,None,14]
print sum(1 for i in lst if i != None)
Two ways:
One, with a list expression
len([x for x in lst if x is not None])
Two, count the Nones and subtract them from the length:
len(lst) - lst.count(None)
I recently released a library containing a function iteration_utilities.count_items
(ok, actually 3 because I also use the helpers is_None
and is_not_None
) for that purpose:
>>> from iteration_utilities import count_items, is_not_None, is_None
>>> lst = ['hey', 'what', 0, False, None, 14]
>>> count_items(lst, pred=is_not_None) # number of items that are not None
5
>>> count_items(lst, pred=is_None) # number of items that are None
1
Use numpy
import numpy as np
list = np.array(['hey', 'what', 0, False, None, 14])
print(sum(list != None))
You could use Counter
from collections
.
from collections import Counter
my_list = ['foo', 'bar', 'foo', None, None]
resulted_counter = Counter(my_list) # {'foo': 2, 'bar': 1, None: 2}
resulted_counter[None] # 2
I needed to make sure that only one param was send on each call. Therefore at least 2 of the variables must be None and this worked for me.
a_list = [param_1, param_2, param_3]
count = a_list.count(None)
if count < 2:
raise error
im pretty sure that using the length of the list minus the number of Nones here sould be the best option for performance and simplicity
>>> list = ['hey', 'what', 0, False, None, 14]
>>> print(len(list) - list.count(None))
5
I’m trying to count things that are not None
, but I want False
and numeric zeros to be accepted too. Reversed logic: I want to count everything except what it’s been explicitly declared as None
.
Example
Just the 5th element it’s not included in the count:
>>> list = ['hey', 'what', 0, False, None, 14]
>>> print(magic_count(list))
5
I know this isn’t Python normal behavior, but how can I override Python’s behavior?
What I’ve tried
So far I founded people suggesting that a if a is not None else "too bad"
, but it does not work.
I’ve also tried isinstance
, but with no luck.
Just use sum
checking if each object is not None
which will be True
or False
so 1 or 0.
lst = ['hey','what',0,False,None,14]
print(sum(x is not None for x in lst))
Or using filter
with python2:
print(len(filter(lambda x: x is not None, lst))) # py3 -> tuple(filter(lambda x: x is not None, lst))
With python3 there is None.__ne__()
which will only ignore None’s and filter without the need for a lambda.
sum(1 for _ in filter(None.__ne__, lst))
The advantage of sum
is it lazily evaluates an element at a time instead of creating a full list of values.
On a side note avoid using list
as a variable name as it shadows the python list
.
lst = ['hey','what',0,False,None,14]
print sum(1 for i in lst if i != None)
Two ways:
One, with a list expression
len([x for x in lst if x is not None])
Two, count the Nones and subtract them from the length:
len(lst) - lst.count(None)
I recently released a library containing a function iteration_utilities.count_items
(ok, actually 3 because I also use the helpers is_None
and is_not_None
) for that purpose:
>>> from iteration_utilities import count_items, is_not_None, is_None
>>> lst = ['hey', 'what', 0, False, None, 14]
>>> count_items(lst, pred=is_not_None) # number of items that are not None
5
>>> count_items(lst, pred=is_None) # number of items that are None
1
Use numpy
import numpy as np
list = np.array(['hey', 'what', 0, False, None, 14])
print(sum(list != None))
You could use Counter
from collections
.
from collections import Counter
my_list = ['foo', 'bar', 'foo', None, None]
resulted_counter = Counter(my_list) # {'foo': 2, 'bar': 1, None: 2}
resulted_counter[None] # 2
I needed to make sure that only one param was send on each call. Therefore at least 2 of the variables must be None and this worked for me.
a_list = [param_1, param_2, param_3]
count = a_list.count(None)
if count < 2:
raise error
im pretty sure that using the length of the list minus the number of Nones here sould be the best option for performance and simplicity
>>> list = ['hey', 'what', 0, False, None, 14]
>>> print(len(list) - list.count(None))
5