基于 Python 中的公共匹配属性将对象列表合并为一致列表 [英] Merge list of objects into consistent list based on common matching attribute in Python
问题描述
我有一个对象列表,我想根据匹配的属性 (id
) 和可选的类参数将这些对象压缩"为较小的对象列表.
I have a list of objects which I want to "compress" into a smaller list of objects based on a matching attribute (id
) and optional class parameters.
class Case:
def __init__(self, id, formtype, age, fever=None, cough=None, gender=None):
self.case_id = case_id
self.form_type = formtype
self.age = age
self.fever = fever
self.cough = cough
self.gender = gender
caselist = [
Case(id="12345", formtype="A", age=12, fever=1, gender="female"),
Case(id="12345", formtype="B", age=12, cough=0),
Case(id="67890", formtype="A", age=34, fever=0, gender="male"),
Case(id="67890", formtype="B", age=34, cough=1),
Case(id="75321", formtype="A", age=2, fever=0, gender="male")
]
我如何获得看起来像这样的新列表?它应该选择 formtype="B"
而不是 formtype="A"
.
How do I get a new list that looks like this? It should choose formtype="B"
over formtype="A"
.
compressed = [
Case("12345", "B", 12, 1, 1, "female"),
Case("67890", "B", 34, 0, 1, "male"),
Case("75321", "A", 2, 0, "male")
]
我试图用字典压缩它,但没有运气:
I tried to compress it with a dict with no luck:
compressed = [Case(id=case.id, formtype=None, age=case.age) for caselist if case.formtype == 'A']
推荐答案
按 id 分组并保留具有B"form_type 的对象,用于具有B"formtype 的重复 id,否则就保留原样,如果您想要使用B 中未设置的任何属性,您可以使用 getattr 和 setattr 迭代属性以设置 B 中任何以前未设置的属性,除非您事先知道设置了什么,否则您无法硬编码要设置的内容或不设置的内容A 和/或 B 中设置的内容:
Group by id and keep the objects that have a "B" form_type for duplicate id's that have a "B" formtype or else just leave as is, if you want to use any attributes not set in "B you can iterate over the attributes using getattr and setattr to set any previously unset attributes in B, you cannot hard code what to set or what not to set unless you know in advance what is set in A and/or what is set in B:
class Case:
def __init__(self, id, formtype, age, fever=None, cough=None, gender=None):
self.case_id = id
self.form_type = formtype
self.age = age
self.fever = fever
self.cough = cough
self.gender = gender
def __iter__(self):
for ele in ["case_id", "form_type", "age",
"fever", "cough", "gender"]:
yield ele
caselist = [
Case(id="12345", formtype="A", age=12, fever=1, gender="female"),
Case(id="12345", formtype="B", age=12, cough=0),
Case(id="67890", formtype="A", age=34, fever=0, gender="male"),
Case(id="67890", formtype="B", age=34, cough=1),
Case(id="75321", formtype="A", age=2, fever=0, gender="male")
]
d = {}
for c in caselist:
if c.case_id not in d:
d[c.case_id] = c
elif d[c.case_id].form_type != "B" and c.form_type == "B":
tmp = d[c.case_id]
for attr in c:
if getattr(c, attr) is None:
setattr(c, attr, getattr(tmp, attr))
d[c.case_id] = c
caselist[:] = d.values()
print(caselist)
这篇关于基于 Python 中的公共匹配属性将对象列表合并为一致列表的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!