微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

在可迭代的事物中计算匹配元素的大多数pythonic方法

如何解决在可迭代的事物中计算匹配元素的大多数pythonic方法

不得不反复遍历列表并不是很好的恕我直言。

我可能会创建一个允许执行以下操作的函数

twos, threes = countmatching(xrange(1,10),
                             lambda a: a % 2 == 0,
                             lambda a: a % 3 == 0)

起点将是这样的:

def countmatching(iterable, *predicates):
    v = [0] * len(predicates)
    for e in iterable:
        for i,p in enumerate(predicates):
            if p(e):
                v[i] += 1
    return tuple(v)

顺便说一句,“ itertools食谱”有一个类似alt4的食谱。

def quantify(seq, pred=None):
    "Count how many times the predicate is true in the sequence"
    return sum(imap(pred, seq))

解决方法

我想输入一些简单的统计数据,例如,所有数字的整数可以除以2,所有数字的整数可以除以3。

我的第一个选择是,虽然只循环遍历列表一次并避免了列表扩展(并牢记分解循环的重构),但看起来却很肿:

(替代项1)

r = xrange(1,10)

twos = 0
threes = 0

for v in r:
  if v % 2 == 0:
    twos+=1
  if v % 3 == 0:
    threes+=1

print twos
print threes

这看起来不错,但是有将表达式扩展到列表的缺点:

(替代2)

r = xrange(1,10)

print len([1 for v in r if v % 2 == 0])
print len([1 for v in r if v % 3 == 0])

我真正想要的是像这样的函数:

(替代项3)

def count(iterable):
  n = 0
  for i in iterable:
    n += 1
  return n

r = xrange(1,10)

print count(1 for v in r if v % 2 == 0)
print count(1 for v in r if v % 3 == 0)

但这看起来很像没有功能就可以完成的事情。最终的变体是这样的:

(替代项4)

r = xrange(1,10)

print sum(1 for v in r if v % 2 == 0)
print sum(1 for v in r if v % 3 == 0)

尽管体积最小(在我的书中可能是最优雅的),但它并不能很好地表达意图。

因此,我对您的问题是:

您最喜欢哪种方法来收集这些类型的统计信息?如果您有更好的东西,请随时提供自己的选择。

为了清除以下混淆:

  • 实际上,我的过滤谓词比这个简单的测试还要复杂。
  • 我要遍历的对象比数字更大,更复杂
  • 我的过滤器功能更加不同,难以将其参数化为一个谓词

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。