Встроенная функция для применения одного выражения с несколькими переменными

1

Существует ли существующая встроенная функция Python, которая назначает две или более переменных и возвращает несколько значений при назначении одного выражения? Например:

гипотетически:

attrs, patterns, weight = [] * 3

такой же как:

attrs, patterns, weight = [], [], []
  • 1
    Я понятия не имею, о чем ты просишь. Что означает «назначает две или более переменных и возвращает несколько значений при назначении одного выражения»?
  • 0
    Он имел в виду присвоение одного и того же значения нескольким переменным без записи значения несколько раз.
Показать ещё 5 комментариев
Теги:

3 ответа

2

Лучший существующий синтаксис для этого

attrs, patterns, weight = [[] for i in range(3)]

что на самом деле не улучшение по сравнению с [], [], []. Это имеет преимущество для сложных выражений, хотя.

Если вам нужна функция, вы столкнетесь с проблемой, заключающейся в том, что функции Python принимают объекты, а не выражения. Функция не может оценивать свои выражения аргумента повторно. Если вы хотите написать функцию, вам нужно заключить выражение в lambda или что-то в этом роде:

def n_times(constructor, n):
    return [constructor() for i in range(n)]

attrs, patterns, weight = n_times(lambda: [], 3)
# or
attrs, patterns, weight = n_times(list, 3)

Есть несколько заманчивых, но неправильных вариантов:

# Mistake
attrs = patterns = weight = []
# Also a mistake
attrs, patterns, weight = [[]]*3

которые присваивают один и тот же список каждой переменной вместо создания отдельных списков, потому что присваивание Python не копирует, а умножение списка не копирует элементы, а только ссылки на элементы.

  • 0
    Да, это так.
  • 0
    Я с нетерпением жду, когда создатели Python интегрируют это в будущую версию Python.
Показать ещё 5 комментариев
0
a = b = c = []

Все переменные независимо установлены на одно и то же значение. (Внимание: тот же изменяемый объект, но это верно для любого множественного присваивания в Python.)

См. Документацию оператора присваивания - target_list "=" несколько target_list "=".

Оператор присваивания оценивает список выражений [...] и назначает один результирующий объект каждому из целевых списков слева направо.

Это было для меня неожиданностью, когда я впервые попробовал это сделать сразу же! Но это работает так, как вы ожидаете.

0

Если вы хотите иметь поведение, которое вы пытаетесь иметь, вы можете создать пользовательский объект, который ведет себя как это выражение: var1, var2, var3 = __OBJECT__ * 3

Вот пример:

from collections.abc import Iterable

class Custom:   
     def __init__(self, initial=[]):
         if not isinstance(initial, Iterable):
             raise ValueError()
         self.initial = initial
         self.args = initial

     def __mul__(self, args):
         self.args = [self.initial[:] for _ in range(args)]
         return self.args

     def __iter__(self):
         for _ in range(len(self.args)):
             yield self.initial

     def __repr__(self):
         return '{}'.format(list(self))

Демо-версия:

$> a, b, c = Custom() * 3
$> print(a, b, c) # [] [] []
$> id(a) == id(b) == id(c) # False

$> a, b, c = Custom(()) * 3
$> print(a, b, c) # () () ()
$> id(a) == id(b) == id(c) # True

Ещё вопросы

Сообщество Overcoder
Наверх
Меню