在特定条件下从列表(或其他可迭代对象)中获取项目数
- 2025-03-19 08:57:00
- admin 原创
- 6
问题描述:
假设我有一个包含大量项目的列表,
l = [ 1, 4, 6, 30, 2, ... ]
我想从该列表中获取满足特定条件的项目数。我的第一个想法是:
count = len([i for i in l if my_condition(l)])
但是如果过滤后的列表也包含大量项目,我认为为过滤结果创建新列表只是浪费内存。就效率而言,恕我直言,上述调用不可能比以下调用更好:
count = 0
for i in l:
if my_condition(l):
count += 1
是否有任何函数式方法来获取满足条件的项目数,而无需生成临时列表?
解决方案 1:
您可以使用生成器表达式:
>>> l = [1, 3, 7, 2, 6, 8, 10]
>>> sum(1 for i in l if i % 4 == 3)
2
甚至
>>> sum(i % 4 == 3 for i in l)
2
True == 1
它利用了和的事实False == 0
。
或者,您可以使用itertools.imap
(python 2)或者简单使用map
(python 3):
>>> def my_condition(x):
... return x % 4 == 3
...
>>> sum(map(my_condition, l))
2
解决方案 2:
您需要的是生成器理解,而不是这里的列表。
例如,
l = [1, 4, 6, 7, 30, 2]
def my_condition(x):
return x > 5 and x < 20
print sum(1 for x in l if my_condition(x))
# -> 2
print sum(1 for x in range(1000000) if my_condition(x))
# -> 14
或者使用itertools.imap
(尽管我认为显式列表和生成器表达式看起来更符合 Python 风格)。
请注意,虽然从示例中看不出来sum
,但你可以很好地编写生成器推导式。例如,
inputs = xrange(1000000) # In Python 3 and above, use range instead of xrange
odds = (x for x in inputs if x % 2) # Pick odd numbers
sq_inc = (x**2 + 1 for x in odds) # Square and add one
print sum(x/2 for x in sq_inc) # Actually evaluate each one
# -> 83333333333500000
这种技术的妙处在于,您可以在代码中指定概念上独立的步骤,而无需强制评估并存储在内存中,直到评估最终结果为止。
解决方案 3:
reduce
如果你喜欢函数式编程,也可以使用
reduce(lambda count, i: count + my_condition(i), l, 0)
这样,您只需进行 1 次传递,并且不会生成中间列表。
解决方案 4:
你可以做类似的事情:
l = [1,2,3,4,5,..]
count = sum(1 for i in l if my_condition(i))
对于每个满足条件的元素,它都会加 1。
解决方案 5:
from itertools import imap
sum(imap(my_condition, l))
解决方案 6:
您可以使用len(list(filter(my_condition, l)))
。filter
返回一个包含所有值的可迭代对象,这样函数True
在应用时就会返回。使用len
after 可以解决这个问题。filter
对象不支持len
,即__len__
,因此list
必须先调用构造函数。
相关推荐
热门文章
项目管理软件有哪些?
热门标签
云禅道AD