根据布尔值对列表中的对象进行计数 属性

Counting Objects in a List according to a Boolean property

我有一个包含布尔值 属性 的对象列表。

我想根据这个布尔值 属性 - None 计算这些对象的数量。

标准库中是否有比完全编写一个循环来迭代它们更高效、更简洁或更符合 Pythonic 的函数?

Counter 似乎不合适,this nor this 解决了问题 - 据我所知。

class MyObject():
    def __init__(self, moniker, booleanVariable):
        self.name = moniker
        self.state = booleanVariable

def _myCounterMethod(list):
    # code goes here
    return counts

myList = []
myList.append(MyObject("objectOne", True))
myList.append(MyObject("objectTwo", False))
myList.append(MyObject("objectThree", None))

counts = _MyCounterMethod(myList)
print(counts)
>>>[('True', 1), ('False', 1), ('None', 1)]

我目前的解决方案:

def _myCounterMethod(list):
    trueCount = 0
    falseCount = 0
    noneCount = 0
    for obj in list:
        if obj.state == True:
            trueCount += 1
        elif obj.state == False:
            falseCount += 1
        elif obj.state == None:
            noneCount += 1
    countsList = [('True', trueCount), ('False', falseCount), ('None', noneCount)]
    return countsList

使用collections.Counter:

import collections


class MyObject():
    def __init__(self, moniker, booleanVariable):
        self.name = moniker
        self.state = booleanVariable


my_list = [MyObject("objectOne", True), MyObject("objectTwo", False), MyObject("objectThree", None)]

counts = collections.Counter(str(e.state) for e in my_list)
print(counts)

输出

Counter({'True': 1, 'False': 1, 'None': 1})

如果需要严格列出输出,请执行:

result = list(counts.items())
print(result)

输出

[('True', 1), ('False', 1), ('None', 1)]

以下似乎有效

from collections import defaultdict

data = defaultdict(int)
class MyObject():
    def __init__(self, moniker, booleanVariable):
        self.name = moniker
        self.state = booleanVariable
myList = []
myList.append(MyObject("objectOne", True))
myList.append(MyObject("objectTwo", False))
myList.append(MyObject("objectThree", None))
for o in myList:
  data[str(o.state)] += 1
print(data)

输出

defaultdict(<class 'int'>, {'True': 1, 'False': 1, 'None': 1})

我建议你实现 .count() 方法

def counter(l):
   iter = [x.state for x in l]
   return ('True', iter.count(True)), ('False', iter.count(False)), ('None', iter.count(None))
>>> counter(myList)
(('True', 1), ('False', 1), ('None', 1))

您已经了解了基于 Counter 的方法,这里是您所拥有内容的简单缩写:

def _myCounterMethod(lst):  # do not shadow `list`
    trueCount = falseCount = noneCount = 0
    for obj in lst:
        trueCount += obj.state is True
        falseCount += obj.state is False
        noneCount += obj.state is None
    return [('True', trueCount), ('False', falseCount), ('None', noneCount)]

我认为最好的方法是:

from collections import Counter
from operator import attrgetter

def _myCounterMethod(lst):
    return Counter(map(attrgetter("state"), lst)).most_common()
    # already a list of tuples

仅当您真正需要打印时才将您需要的任何内容转换为字符串。