You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何高效获取对象列表中第i个属性的求和列表?

Dynamic Property Summation for Object Lists

Great question—this is such a common pain point when working with objects that have lots of properties, especially when their names aren’t nicely numbered like a1, a2! Let’s break down how to solve this cleanly and efficiently, without hardcoding every single property.

First: Stop Hardcoding Property Names

The key here is to dynamically access the properties of your Foo objects instead of writing x.a1, x.a2, etc. Python gives you a few straightforward ways to do this:

1. Use vars() to Fetch Object Properties

For most simple classes (without __slots__ defined), vars(obj) returns a dictionary of the object’s attributes and values. We can use this to grab all property names from the first object in your list (assuming all Foo objects share the same properties):

# Get all property names from the first object in the list
property_names = list(vars(l[0]).keys())

# Calculate sums dynamically with a list comprehension
sums = [sum(getattr(obj, prop) for obj in l) for prop in property_names]
  • getattr(obj, prop) lets us dynamically fetch the value of the property named prop from obj—no hardcoding needed.
  • Using a generator expression (getattr(...) for obj in l) instead of a list comprehension saves memory, especially with large lists, since we don’t create an intermediate list before summing.

2. Preserve Property Definition Order

If you need the sums to match the exact order in which properties were declared in the Foo class (instead of dictionary order), use these approaches based on your setup:

For Dataclasses (Python 3.7+):

If you define Foo as a dataclass, you can get properties in their original declaration order:

from dataclasses import dataclass, fields

@dataclass
class Foo:
    a1: int
    a2: int
    a3: int

# Get property names in the order they were defined
property_names = [field.name for field in fields(Foo)]

# Calculate sums
sums = [sum(getattr(obj, prop) for obj in l) for prop in property_names]

For Regular Classes:

Use the inspect module to filter for instance attributes (skip methods and class-level properties):

import inspect

def get_instance_properties(obj):
    return [name for name, _ in inspect.getmembers(obj, lambda attr: not inspect.ismethod(attr))]

property_names = get_instance_properties(l[0])
sums = [sum(getattr(obj, prop) for obj in l) for prop in property_names]

Optimize for Large Lists: Cut Down on Loop Overhead

Your original approach (and the dynamic list comprehension above) loops through the entire list n times (once per property). If your list l is very large (thousands/millions of objects), you can optimize by looping through the list once and accumulating sums as you go:

if not l:
    sums = []  # Handle empty list edge case
else:
    # Initialize sums with the first object's property values
    first_obj = l[0]
    property_names = list(vars(first_obj).keys())
    sums = list(vars(first_obj).values())

    # Iterate through remaining objects and add their values to the sums
    for obj in l[1:]:
        for idx, prop in enumerate(property_names):
            sums[idx] += getattr(obj, prop)

This has the same time complexity (O(n*m) where n is property count and m is object count), but it reduces full list traversals from n to 1—this can make a noticeable speed difference with huge datasets.

Key Notes to Avoid Issues

  • Consistent Properties: All Foo objects in the list must have the same properties. If some objects are missing properties, add a safety check like getattr(obj, prop, 0) to use 0 as a default value.
  • Filter Non-Integer Properties: If Foo has non-integer attributes, filter them out first:
    property_names = [name for name, val in vars(l[0]).items() if isinstance(val, int)]
    

内容的提问来源于stack exchange,提问作者LeetCoder

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 06:59:42