【问题标题】:Python: Appending to multiple lists from function returnPython:从函数返回附加到多个列表
【发布时间】:2020-07-21 20:13:49
【问题描述】:

我正在寻找一种 Python 方式来从函数返回的元组中追加到多个列表。

所以转这个:

def f():
  return (1,2)

a = []
b = []
for c in container:
  r1, r2 = f()
  a += [r1]
  b += [r1]

变成这样的:

for c in container:
  a, b += f()

我的代码有点复杂(在循环中做了几个操作),我有一个使用 zip 和列表理解的版本,但它有点不可读:

list1, list2, list3 = zip (*[
           c( list(img.to(devices[i]) for img in images),
              features[i],
              [{k: v.to(devices[i]) for k, v in t.items()} for t in targets]
            )
            for i, c in enumerate(container)
        ])

如果我可以将列表推导式转换为常规 for 并具有紧凑的附加方式,我认为可读性会提高很多。

提前致谢!

【问题讨论】:

    标签: python


    【解决方案1】:

    所以,对于这样的事情:

    def f():
      return (1,2)
    
    a = []
    b = []
    for c in container:
      r1, r2 = f()
      a += [r1]
      b += [r1]
    

    将您的目标列表放在另一个列表中,然后使用zip 迭代比和相应的结果:

    accumulators = [a, b]
    for c in container:
        for acc, result in zip(accumulators, f()):
            acc.append(result) # NOT acc += [result]
    

    你是对的,这个巨大的嵌套列表理解是完全不可读的。你也在这里滥用zip。这个小技巧有时还可以,但在这种情况下,它只是掩盖了正在发生的事情。您应该使用zip 同时迭代多个可迭代对象,不要使用i 索引来执行此操作。使用临时变量来保存您的中间结果,我称它们为 arg1arg3,但为您的用例使用描述性名称。看看这有多干净,你可以很容易地跟踪发生了什么:

    accumulators = [list1, list2, list3]
    for container, device feature in zip(containers, devices, features):
    
        arg1 = [img.to(device) for img in images]
        arg3 = [{k: v.to(device)} for k,v in t.items()} for t in targets]
        results = container(arg1, feature, arg2)
    
        for accumulator, result in zip(accumulators, results):
            accumulator.append(result)
    

    【讨论】:

    • 谢谢!我最终使用了一个非常相似的解决方案,但我在开头有 accumulators = [[], [], []] 来定义列表并在循环 list1, list2, list3 = proposals 之后“解压”它们
    猜你喜欢
    • 1970-01-01
    • 2017-01-16
    • 2013-10-28
    • 2020-05-03
    • 2018-05-02
    • 1970-01-01
    • 2017-02-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多