【问题标题】:Python: Summing class instances inside a listPython:在列表中汇总类实例
【发布时间】:2011-10-18 17:42:18
【问题描述】:

我熟悉列表的内置 sum() 函数并且之前使用过它,例如:

sum(list1[0:41])

当列表包含整数时,但我的情况是我有一个类中的实例,我需要对它们求和。

我有这个课程:

class DataPoint:
    def __init__(self, low, high, freq):
        self.low = low
        self.high = high
        self.freq = freq

它们都引用 XML 文件中的浮点数,这些实例稍后会进入我的代码中的列表。

例如,我希望能够执行以下操作:

sum(list[0:41].freq)

其中列表包含 Class 实例。

我也试图在一个循环中得到它,以便 sum() 范围内的第二个数字每次都上升,例如:

for i in range(len(list)):
    sum(list[0:i+1].freq)

任何人都知道我该如何解决这个问题,或者是否有其他方法可以做到这一点?

谢谢!

更新:

感谢所有回复,我将尝试提供比我首先提出的概念性内容更具体的内容:

# Import XML Parser
import xml.etree.ElementTree as ET

# Parse XML directly from the file path
tree = ET.parse('xml file')

# Create iterable item list
items = tree.findall('item')

# Create class for historic variables
class DataPoint:
    def __init__(self, low, high, freq):
        self.low = low
        self.high = high
        self.freq = freq

# Create Master Dictionary and variable list for historic variables
masterDictionary = {}

# Loop to assign variables as dictionary keys and associate their values with them
for item in items:
    thisKey = item.find('variable').text
    thisList = []
    masterDictionary[thisKey] = thisList

for item in items:
    thisKey = item.find('variable').text
    newDataPoint = DataPoint(float(item.find('low').text), float(item.find('high').text), float(item.find('freq').text))
    masterDictionary[thisKey].append(newDataPoint)

# Import random module for pseudo-random number generation
import random

diceDictionary = {}

# Dice roll for historic variables
for thisKey in masterDictionary.keys():
    randomValue = random.random()
    diceList = []
    diceList = masterDictionary[thisKey]
    for i in range(len(diceList)):
        if randomValue <= sum(l.freq for l in diceList[0:i+1]):
            diceRoll = random.uniform(diceList[i].low, diceList[i].high)
            diceDictionary[thisKey].append(diceRoll)

我基本上是在尝试创建一个骰子字典,以将我的主字典的键与数据相匹配。我的类的 freq 实例是指应用某些 bin 的概率,由掷骰子(随机数)确定。这就是求和的目的。

也许这有助于澄清我的意图?求和示例中的“i”将是某个变量的数据点数。

一旦我有了在我的输出循环中选择了哪些卷的字典(此处未显示),我将把它应用到下面的代码中以使一些有意义的东西。

如果我的意图仍有任何混淆,请告诉我。我将尝试其中一些建议,但考虑到我提供的内容,也许有人可以将其分解为最简单的形式。

谢谢!

【问题讨论】:

    标签: python class list sum instances


    【解决方案1】:

    你试过了吗:

    sum(i.freq for i in items[0:41])
    

    如果您需要最后“i”个元素的累积和,以下是最有效的方法:

    sums = [items[0].freq]
    for i in items[1:]:
        sums.append(sums[-1] + i.freq)
    

    正如其他发帖人已经预料到的那样,为变量使用内置名称是一种糟糕的编程风格;我在上面的代码中用items 替换了list

    【讨论】:

    • 当放在一个循环中时,这将具有二次复杂度,但是
    • @Cameron 整数值之和如何具有二次复杂度?
    • @JBernardo:将 0i + 1 的项目相加为 O(n)。这样做 n 次是 O(n^2)。 OP 提议为每个 i 做一个总和。
    • @Cameron Dude 我不明白你的意思。它的复杂性相同。我想你应该再读一遍这个问题
    • @Cameron, JBernardo:我认为我复制了错误的行,现在更正。是的,每个线性算法在放置在循环中时都会以二次方式表现...... :)
    【解决方案2】:

    您的最后一个示例将具有二次复杂度。一个更简单的方法是只保留一个运行总数:

    total = 0
    for x in list:
        total += x.freq  # total at this point is equal to the sum in your example
    # and total at this point is the grand total
    

    如果您不需要列表中每个项目的运行总和,而只需要总计,请参考GaretJax's answer,它使用sum

    另外,list 是一个内置类型,所以您可能不想将它用作变量名(这会覆盖内置)。

    【讨论】:

    • 整数值之和如何具有二次复杂度?为什么for循环比c中写的sum函数更好?
    • @JBernardo: 做 n 个总和比做一个总和更快(无论如何是渐近的)?
    • 这不是n 的总和。最后一个例子是错误的(它是伪代码)。 SUM 是一个以您的方式实现但速度更快的函数
    • @JBernardo:我假设 OP 发布了他的意思。我只提到了他的最后一个例子(他想要每一步的总和)
    • @JBernardo:因为他想要每一步的总和,而不仅仅是最终的总数
    【解决方案3】:

    对于第一个用例,类似

    sum(dp.freq for dp in dp_list[:41])
    

    很可能是合适的。

    但是,如果您无论如何都想做累积和,从技术上讲,您可以将它们组合起来,因为总和将是最后的总和。例如,

    cumsums = []
    for i, dp in enumerate(dp_list):
        if cumsums:
            cumsums.append(dp.freq + cumsums[-1])
        else:
            cumsums.append(dp.freq)
    

    然后cumsums[40] 将是前 41 个DataPoints 的频率之和。您甚至可以进一步优化上面的代码(也许将if/else 替换为try/except IndexError,但重要的是它的正确性。

    次要考虑

    你可能想使用一个新风格的类,所以而不是

    class DataPoint:
    

    你会的

    class DataPoint(object):
    

    此外,您可以删除列表切片中的初始 0,因为在几乎所有意图和目的上,lst[:41]lst[0:41] 相同。

    【讨论】:

      【解决方案4】:

      当列表包含整数时,但我的情况是我有一个类中的实例,我需要对它们求和。

      关键是要理解您不想对类实例求和(这首先需要定义两个类实例的相加),而是对每个freq 的一些成员 求和。因此,我们要求求和:实例列表中每个给定实例的.freq 的总和。如果我们接受我们需要为列表实例提供一个临时名称(以便我们可以访问.freq),那么相应的 Python 代码将尽可能清晰地读取(请参阅 GaretJax 的答案)。

      您的语法请求子列表的.freq,这当然不存在。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2018-07-12
        • 2012-09-07
        • 1970-01-01
        • 1970-01-01
        • 2017-09-07
        • 1970-01-01
        • 2023-04-03
        相关资源
        最近更新 更多