【问题标题】:Sum list up until element changes, then start again汇总列表直到元素更改,然后重新开始
【发布时间】:2013-05-30 07:41:41
【问题描述】:

一旦一个元素的名称发生变化,是否有某种方法遍历列表并对列求和。

[['a','1'],['a','2'],['a','3']....on and on, ['b','1'],['b','2'],['b','3']...
on and on....]]

因此,当 [0] 处有 'a' 时,对索引 1 列求和,然后如果 [0] 发生变化(即 'b'),则再次开始求和。所以我想这可能是一种while循环,但无法弄清楚。我的想法是(但显然是错误的)......

    for row in list:
        for i in row:  #iterate through each row
            var = i[0] #assign first index to 'var'
            while True: #while var is one name
                for num in lst:
                    sum(float(num[1]) for num in lst if num[1])   #add column [1]
            ....then something else...

一些事情-我不想指定元素名称('a','b'..),因为它会改变。 元素类型的数量也可能发生变化——有时只是'a'、'b',有时是'c'、'd'、'e'等 每次第一个元素发生变化时,我都需要以某种方式存储总和值

这可能不使用字典或模块等吗?

【问题讨论】:

  • 字典有什么问题?
  • 您提到您不想使用dict...您的意思是您不想存储为dict,还是不想使用@987654325 @在您的解决方案中?我问是因为在解决方案中使用dict 可能会更容易。
  • 不使用 dict 或模块使它看起来像是一个家庭作业问题。如果是这种情况,您应该提及

标签: python list sum


【解决方案1】:

使用itertools.groupby() 对您的项目进行分组:

from itertools import groupby
from operator import itemgetter

sums = [(key, sum(float(i[1]) for i in group))
        for key, group in groupby(row, key=itemgetter(0))]

这会生成('a', 10.0) 等值的列表。

groupby() 工具将您的输入序列分成组,其中下一组由 key 可调用项确定;当key 可调用的返回值发生变化时,会产生一个新组。

【讨论】:

  • 所以key=itemgetter(0)中提到的0其实就是改变的item的索引号??
  • @Op.Ivy:是的,itemgetter(0) 为列表中的每个值返回索引 0 处的项目。所以row[0][0]arow[1][0] 也是a,所以这是同一个组,等等,直到你到达row[n][0],它是b,所以这是一个新组。
【解决方案2】:

这是itertools.groupby() 的完美用例,它允许您对来自一个可迭代对象的元素进行分组。它可能看起来像这样:

from itertools import groupby
from operator import itemgetter
data = [['a','1'],['a','2'],['a','3'], ['b','1'],['b','2'],['b','3'],['b','4']]
sums = [(k, sum(float(v) for k, v in g)) for k, g in groupby(data, key=itemgetter(0))]

结果:

>>> sums
[('a', 6.0), ('b', 10.0)]

【讨论】:

  • 值得注意的是,如果值始终是整数,就像 OP 的问题一样,int() 可能比float() 更可取。此外,如果数据没有以开头排序(尽管它似乎在示例中),则需要进行排序。
  • 同意,我只使用float() 与OP的代码保持一致。
【解决方案3】:

在这种情况下,由于您正在添加内容,因此可以使用计数器

>>> from collections import Counter
>>> L = [['a', '1'], ['a', '2'], ['a', '3'], ['b', '1'], ['b', '2'], ['b', '3']]
>>> c = Counter()
>>> for i,j in L:
...  c.update({i: float(j)})
... 
>>> c
Counter({'a': 6.0, 'b': 6.0})

【讨论】:

  • 如果a 密钥稍后再次出现并且 OP 希望该组单独相加怎么办?从这个问题我推断应该只对连续的键求和。
  • @MartijnPieters,那么它可能不是 OP 想要的。我猜这取决于键是否可以再次出现。
  • 它们总是连续的
猜你喜欢
  • 2019-05-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-02-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多