有没有一种方法可以在Python算法的迭代之间保存值?

rvpgvaaj  于 2023-03-28  发布在  Python
关注(0)|答案(1)|浏览(155)

我有一个类,它将一些数据打印到CSV文件中。数据由我代码中其他地方的算法计算,结果列表发送到下面的方法。结果中有一个元素,我们想看看它是如何从以前的结果中改变的,并保存这些值以供将来比较。我将这些值保存在一个字典中,在该字典中我使用(我得到的另一个值)作为键,但现在我遇到了一个测试用例,其中两个类型具有相同的名称,并且没有其他不可变的值可以使用。这在代码的其他地方都不是问题(算法不关心它们的名字)但我对如何区分它们感到茫然,结果应该每次都是相同的顺序,但我不想指望这个。
我能想到的最好的解决方案是在名称的末尾添加一个$符号(见下面的修补程序),但这看起来很草率,仍然依赖于相同顺序的值。或者,我可以创建一个列表或数组而不是字典,这将更整洁但更依赖于顺序。

from csv import writer

class CSVPrinter():
    def __init__(self, filename=None):
        self.filename = filename if filename else "test_file"
        self.prev_totals = {}

    def write(self, rows):
        """ Write given rows to CSV file """
        with open(self.filename, "a", encoding="utf-8") as csv_file:
            writer(csv_file).writerows(rows)

    def print_results(self, results):
        """ Print results (already calculated) """
        new_totals = {}
        sum_change = 0
        for res in results:
            title = res[0]
            while title in new_totals:
                title += "$"  # hotfix
            change = res[4] - self.prev_totals.get(title, 0)
            res.append(round(change, 4))
            new_totals[title] = res[4]
            sum_change += change
        self.write(
            results + [["", "", "", "", "", round(sum_change, 4)]]
        )
        self.prev_totals = new_totals

csvp = CSVPrinter("test_file")
# Print sample data. Normally print_results() would be called from within the algorithm.
csvp.print_results([["Res_A", 100, 200, 100, 100], ["Res_A", 200, 200, 300, 200], ["Res_B", 400, 200, 300, 200]])
csvp.print_results([["Res_A", 100, 300, 0, 200], ["Res_A", 200, 300, 100, 200], ["Res_B", 200, 0, 50, 500]])

预期成果:(csv)

Res_A,100,200,100,100,100
Res_A,200,200,300,200,200
Res_B,400,200,300,200,200
,,,,,500
Res_A,100,300,0,200,100
Res_A,200,300,100,200,0
Res_B,200,0,50,500,300
,,,,,400

有没有一种更简洁的方法来处理这个问题,而不必创建更多的数据(比如在系统的其他地方创建一个唯一的ID)?

uelo1irk

uelo1irk1#

存储记忆值的字典需要一个id和一个存储值。如果你不能依赖(或不想生成)一个唯一的ID,那么第二个可用的选项是将与非唯一键关联的值存储在列表或其他集合数据类型中。这允许你通过现有键存储和检索内容,而不用担心。
例如,该结构的示例可以是:

mem_store = { "name1" : [ 1, 4, 55 ], 
              "name2" : [ 6 ] , 
              "name3" : [ 4 ] ,
              "name4" : [ 3, 6, 99 ] }

当然,处理这些数据值的函数必须进行更改,以适应将它们作为列表读取。这可能不切实际,但您没有提到您的比较函数具体做了什么,所以我假设可以通过这种方式进行一些比较。
如果是简单的sumavg或其他数字聚合,那么这应该可以很好地解决。

相关问题