一直在思考如果可能的话如何将它转换成一个班轮:
activities = 
[ {'type': 'Run', 'distance': 12345, 'other_stuff': other ...},                   
  {'type': 'Ride', 'distance': 12345, 'other_stuff': other ...},  
  {'type': 'Swim', 'distance': 12345, 'other_stuff': other ...} ] 目前正在使用:
grouped_distance = defaultdict(int)
for activity in activities:  
    act_type = activity['type']
    grouped_distance[act_type] += activity['distance']
# {'Run': 12345, 'Ride': 12345, 'Swim': 12345} 试过
grouped_distance = {activity['type']:[sum(activity['distance']) for activity in activities]}
在没有定义活动“类型”的情况下,这是不起作用的。
编辑的
修正@Samwise注意到的一些变量错误
更新:对发布的所有解决方案都做了一些基准测试。10 000 000件物品,有10种不同类型:
方法1(计数器):7.43s
方法2 (itertools @chepner):8.64s
方法3(group @Dmig):19.34s
方法4(熊猫@d.b):32.73s
方法5 (Dict @d.b):10.95s
在Raspberry Pi 4上进行测试,以进一步了解其差异。如果我说错了这个方法,一定要纠正我。
谢谢大家和“Dmig,”马克,@juanpa.arrivillaga激发了我对表演的兴趣。更短/更整洁的≠更高的性能。我只想问一下,我是否把它写成了一个线条形式,使它看起来更整洁,但我已经学到了更多的东西。
发布于 2022-05-27 20:40:20
你的解决方案是好的,但如果你真的想要一条线:
act = [{'type': 'run', 'distance': 4}, {'type': 'run', 'distance': 3}, {'type': 'swim', 'distance': 5}]
groups = {
  t: sum(i['distance'] for i in act if i['type'] == t)
  for t in {i['type'] for i in act}  # set with all possible activities
}
print(groups)  # {'run': 7, 'swim': 5}UPD:我做了一些性能研究,比较了这个答案和使用group(sortedby(...))的答案。结果,在1千万个条目和10种不同类型上,这种方法在18.14秒对10.12的情况下输给了10.12。因此,虽然它更具可读性,但在较大的列表上效率较低,特别是其中包含更多不同类型的列表(因为它对每个不同类型的初始列表迭代一次)。
但是请注意,从问题中开始的直接方式将只需要5秒!
这个答案只是为了教育目的展示一条条线,从问题中解决问题有更好的表现.你不应该使用这个,而不是一个问题,除非,正如我所说,你真的想/需要一个-线。
发布于 2022-05-27 21:00:29
from operator import itemgetter
by_type = itemgetter('type')
distance = itemgetter('distance')
result = {
    k: sum(map(distance, v))
    for k, v in groupby(sorted(activities, key=by_type), by_type)
    }在groupby实例上迭代时,k将是活动类型之一,而v将是具有k类型的活动的可迭代性。
https://stackoverflow.com/questions/72410741
复制相似问题