首页 > 解决方案 > python: filter() 一个可迭代的,计数过滤和未过滤的项目

问题描述

我有一个大Iterable.
我想用filter()函数过滤它。
我如何计算(以某种优雅的方式)过滤了多少项目?
(同样的问题可能是map()reduce()

我当然可以:

items = get_big_iterable()
count_good = 0
count_all = 0
for item in items:
    if should_keep(item):
        count_good += 1
    count_all += 1

print('keep: {} of {}'.format(count_good, count_all))

有可能filter()吗?

items = filter(should_keep, get_big_iterable()) 
    for item in items:
        #... using values here ..
        #possible count not filtered items here too? 

我不应该迭代两次,并且想使用filter()或类似的解决方案

标签: pythonpython-3.xdictionaryfilteriterator

解决方案


它应该很简单enumerate,还有一些基本的算术:

def should_keep(x):
    return x % 3 == 0

items = range(1, 28)


def _wrapper(x):
    return should_keep(x[1])

filtered_with_counts = enumerate(filter(_wrapper, enumerate(items, 1)), 1)

for i, (j, item) in filtered_with_counts:
    # do something with item
    print(f"Item is {item}, total: {j}, good: {i}, bad: {j-i}")

count_all = j
count_good = i
count_bad = count_all - count_good
print(f"Final: {count_all}, {count_good}, {count_bad}")

输出:

Item is 3, total: 3, good: 1, bad: 2
Item is 6, total: 6, good: 2, bad: 4
Item is 9, total: 9, good: 3, bad: 6
Item is 12, total: 12, good: 4, bad: 8
Item is 15, total: 15, good: 5, bad: 10
Item is 18, total: 18, good: 6, bad: 12
Item is 21, total: 21, good: 7, bad: 14
Item is 24, total: 24, good: 8, bad: 16
Item is 27, total: 27, good: 9, bad: 18
Final: 27, 9, 18

不过我可能不会用这个。请注意,我假设您可能不想修改should_keep,但您始终可以包装它。


推荐阅读