看这个:
from itertools import chain, filterfalse
def zeroCount(m):
total = 0
for x in filterfalse(bool, chain(*m)):
total += 1
return total
在Python 3.3.3上进行性能测试:
from timeit import timeit
from itertools import chain, filterfalse
import functools
m = ((2,0,2,2),(4,4,5,4),(0,9,4,8),(2,2,0,0))
def zeroCountOP():
return [item for row in m for item in row].count(0)
def zeroCountTFE():
return len([item for row in m for item in row if item == 0])
def zeroCountJFS():
return sum(row.count(0) for row in m)
def zeroCountuser2931409():
return functools.reduce(lambda a, b: a + b, m).count(0)
def zeroCount():
total = 0
for x in filterfalse(bool, chain(*m)):
total += 1
return total
print('Original code ', timeit(zeroCountOP, number=100000))
print('@J.F.Sebastian ', timeit(zeroCountJFS, number=100000))
print('@thefourtheye ', timeit(zeroCountTFE, number=100000))
print('@user2931409 ', timeit(zeroCountuser2931409, number=100000))
print('@frostnational ', timeit(zeroCount, number=100000))
上述操作给我带来了以下结果:
Original code 0.244224319984056
@thefourtheye 0.22169152169497108
@user2931409 0.19247795242092186
@frostnational 0.18846473728790825
@J.F.Sebastian 0.1439318853410907
@J.F.Sebastian的解决方案是胜者,我的方案是亚军(速度慢约20%)。
关于Python 2和Python 3的全面解决方案:
import sys
import itertools
if sys.version_info < (3, 0, 0):
filterfalse = getattr(itertools, 'ifilterfalse')
else:
filterfalse = getattr(itertools, 'filterfalse')
def countzeros(matrix):
''' Make a good use of `itertools.filterfalse`
(`itertools.ifilterfalse` in case of Python 2) to count
all 0s in `matrix`. '''
counter = 0
for _ in filterfalse(bool, itertools.chain(*matrix)):
counter += 1
return counter
if __name__ == '__main__':
from timeit import repeat
print(repeat('countzeros(((2,0,2,2),(4,4,5,4),(0,9,4,8),(2,2,0,0)))',
'from __main__ import countzeros',
repeat=10,
number=100000))