Python: добавление в несколько списков из функции return - PullRequest
0 голосов
/ 09 апреля 2020

Я ищу pythoni c способ добавления к нескольким спискам из кортежа, возвращаемого функцией.

Таким образом, это превращается:

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()

Мой код немного сложнее (выполняет несколько операций внутри l oop), и у меня есть версия, использующая 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)
        ])

Если я смогу превратить понимание списка в обычный для и иметь компактный способ добавления, я думаю, что удобочитаемость значительно улучшится.

Заранее спасибо!

1 Ответ

0 голосов
/ 09 апреля 2020

Итак, для чего-то подобного:

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 для этого. Используйте временные переменные для хранения ваших промежуточных результатов, я назвал их arg1 и arg3, но использовал описательное имя для вашего варианта использования. Посмотрите, насколько это чище, вы можете легко следить за тем, что происходит:

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)
...