【问题标题】:How to group two lists of class objects based on an Attribute efficiently in Python?如何在 Python 中根据属性有效地对两个类对象列表进行分组?
【发布时间】:2020-04-17 10:39:16
【问题描述】:

我有两个列表,它们都包含来自同一类的对象。我想将它们组合在第三个列表中,其中包含具有相同属性值的对象的列表或元组。

例子

Object1.time = 1 
Object2.time = 2
Object3.time = 1
Object4.time = 2
Objekt5.time = 3


list1 = [Object1, Object2]
list2 = [Object3,Object4]

排序结果应该是这样的:

result_list = [[Object1,Object3], [Object2,Object4], [Object5]]

我需要提一下:我不需要只包含一个对象的列表!

因此,最终列表应如下所示:

final_result = [[Objekt1, Objekt3], [Objekt2, Objekt4]]

List1 包含 1500 个对象,List2 超过 70,000 个问题是:如果我使用两个 for 循环来比较对象,则花费的时间太长。

这是我的低效示例:

class Example:
    def __init__(self,time,example_attribute):
        self.time = time
        self.example_attribute = example_attribute

test_list1 = [1,1,2,3,4,5,6,6,7,8,9,9]
test_list2 = ["a","b","c","d","e","f","d","e","f","g","h","i"]

test_list3 = ["j","k","l","m","n","o","p","q","r","s","t","u"]


object_list1 = []
for i,j in zip(test_list1,test_list2):
    object_list1.append(Example(i,j))

object_list2 = []
for i,j in zip(test_list1,test_list3):
    object_list2.append(Example(i,j))


# How to group both lists together by the time attribute? This part takes too long.
group_by_time = []
for i in object_list1:
    my_list = [i]
    for j in object_list2:
        if i.time == j.time:
            my_list.append(j)
    group_by_time.append(my_list)

for sub_list in group_by_time:
    for index, item in enumerate(sub_list):
        if index == 0:
            print(item.time, ",",item.example_attribute,end =",")
        else:print(item.example_attribute, end = ",")
    print("")```

【问题讨论】:

    标签: python performance loops class for-loop


    【解决方案1】:

    使用字典,这是您惯用的分组方式:

    import itertools
    
    grouped = {}
    for obj in itertools.chain(list1, list2):
        grouped.setdefault(obj.time, []).append(obj)
    

    现在您有了一个字典,将时间属性映射到对象列表。如果你真的想要,你可以得到一个列表列表,比如:

    final = list(grouped.values())
    

    如果你想省略只有一个值的列表,你可以这样做:

    final = [v for v in grouped.values() if len(v) > 1]
    

    【讨论】:

    • 非常感谢!我完全专注于列表,我没有考虑字典!
    • 我有一个问题,我可以用list1 + list2 代替itertools.chain() 吗? itertools在这里有什么优势吗?
    • @RaphaelPrinz 是的,你可以,但使用 chain 不会创建另一个列表。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-05-23
    • 2023-02-07
    • 2021-06-27
    • 1970-01-01
    相关资源
    最近更新 更多