Python:合并对象“identity”不相等的两个列表

2024-09-30 20:34:23 发布

您现在位置:Python中文网/ 问答频道 /正文

我试图合并两个列表,baseoverride,其中base应该是一个更大的列表,overridebase中事物的子集。在元素重叠的地方,我希望base中的对象被override中的对象覆盖。每个列表中的对象都是具有属性al2000de2000的namedtuple。此外,当对象具有相同的al2000de2000值时,我希望将它们视为“相同的”。我有什么(这似乎是工作)如下,但这有嵌套循环,我想知道是否有更好的方法来做到这一点。你知道吗

# Part of a function
final = []
for i in base:
    if all((i.al2000, i.de2000) != (k.al2000, k.de2000) for k in override):
        final.append(i)
    else:
        for k in override:
            if (i.al2000, i.de2000) == (k.al2000, k.de2000):
                final.append(k)
return final

Tags: 对象in元素列表forbaseif地方
3条回答

你可以用一本字典和一些字典的理解。你知道吗

uniques = {(x.al2000, x.de2000): x for x in base}
uniques.update({(x.al2000, x.de2000): x for x in override})
final = uniques.values()

编辑以保留在override中省略额外值的原始行为。你知道吗

uniques = {(x.al2000, x.de2000): x for x in base}
for value in override:
    key = value.al2000, value.de2000
    if key in uniques:
        uniques[key] = value
# here's the comprehension version, although it's a bit rough on the eyes
# uniques.update({(x.al2000, x.de2000): x for x in override if (x.al2000, x.de2000) in uniques})
final = uniques.values()

您可以使用for/else构造。你知道吗

final = []
for i in base:
    for k in override:
        if (i.al2000, i.de2000) == (k.al2000, k.de2000):
            # found an override
            final.append(k)
            break
    else:
        final.append(i)

这个解决方案仍然使用嵌套for循环,但是它从原始解决方案中删除了代码重复(迭代overrides,比较ik)。你知道吗

这个答案采纳了@acushner的建议,使用dict,这可能是最自然的方法。此外,在处理重写时,^{}非常有用,而且在许多情况下是表示数据结构的最自然的方式。你知道吗

from collections import ChainMap
base_dct = {(x.al2000, x.de2000): x for x in base}
override_dct = {(x.al2000, x.de2000): x for x in override}
z = ChainMap(base_dct, override_dct)
# then access:
z.values()
# or:
z[(x.al2000, x.de2000)]

有关链映射的详细信息,请参见this question。你知道吗

相关问题 更多 >