最短的计数方式?
Shortest way of counting?
假设我有一个 MyClass
的列表。我想计算 MyClass.SomeProperty
设置为 True
的元素的数量(假设 SomeProperty
是一个布尔值,它总是 True
或 False
)。我的顾虑是:
- 应该运行快
- 代码读起来应该不会混淆
- 它应该适用于任何类型的条件(不仅仅是布尔值)
我知道我能做到:
count = len([e for e in MyList if e.SomeProperty]) # For non booleans, something like e.SomeProperty == MyValue
但是好像效率不高
- 为什么要输入像
e for e
这样毫无意义的东西?
- 当您只想计算它们时,为什么要创建一个完整的列表?
是否可以做得更好?
您可以将 sum
与生成器表达式一起使用。
count = sum( e.SomeProperty for e in MyList )
或者对于一般谓词 p
:
count = sum( p(e) for e in MyList )
这利用了 True 和 False 可以用作整数 1 和 0 的事实,并且使用生成器这一事实将阻止创建新列表。
如果你坚持要避免 for e in
部分,你可以使用 map
和 attrgetter
:
import opertor
count = sum(map(operator.attrgetter('SomeProperty'), MyList))
或者对于一般谓词 p
:
count = sum(map(p, MyList))
但是,这不是 pythonic。我推荐第一种方法。
你的意思是:
count = sum(bool(e.SomeProperty) for e in MyList)
与其他类似,但更像 Pythonic 恕我直言:
sum(1 for e in MyList if e.SomeProperty)
或者如果你不在乎懒惰:
len([e for e in MyList if e.SomeProperty])
假设我有一个 MyClass
的列表。我想计算 MyClass.SomeProperty
设置为 True
的元素的数量(假设 SomeProperty
是一个布尔值,它总是 True
或 False
)。我的顾虑是:
- 应该运行快
- 代码读起来应该不会混淆
- 它应该适用于任何类型的条件(不仅仅是布尔值)
我知道我能做到:
count = len([e for e in MyList if e.SomeProperty]) # For non booleans, something like e.SomeProperty == MyValue
但是好像效率不高
- 为什么要输入像
e for e
这样毫无意义的东西? - 当您只想计算它们时,为什么要创建一个完整的列表?
是否可以做得更好?
您可以将 sum
与生成器表达式一起使用。
count = sum( e.SomeProperty for e in MyList )
或者对于一般谓词 p
:
count = sum( p(e) for e in MyList )
这利用了 True 和 False 可以用作整数 1 和 0 的事实,并且使用生成器这一事实将阻止创建新列表。
如果你坚持要避免 for e in
部分,你可以使用 map
和 attrgetter
:
import opertor
count = sum(map(operator.attrgetter('SomeProperty'), MyList))
或者对于一般谓词 p
:
count = sum(map(p, MyList))
但是,这不是 pythonic。我推荐第一种方法。
你的意思是:
count = sum(bool(e.SomeProperty) for e in MyList)
与其他类似,但更像 Pythonic 恕我直言:
sum(1 for e in MyList if e.SomeProperty)
或者如果你不在乎懒惰:
len([e for e in MyList if e.SomeProperty])