Распаковка аргументов для передачи в функцию Python
Бывают ситуации, когда для функции, требующей отдельных позиционных аргументов, значения этих аргументов уже находятся в списке или кортеже, и для вызова функции должны быть распакованы.
Например, встроенная range() функция ожидает отдельные аргументы start и stop . Если они не доступны отдельно, то можно распаковать аргументы из списка list или кортежа tuple , вызвав функцию с переменной этого списка/кортежа, а впереди нее поставить символ одной звездочки * :
# обычный вызов с отдельными аргументами >>> list(range(3, 6)) # [3, 4, 5] >>> args = [3, 6] # вызов с аргументами, распакованными из списка >>> list(range(*args)) # [3, 4, 5]
Таким же образом, из словаря dict в функцию можно передать ключевые аргументы, только в этом случае, перед переменной словаря ставится два символов звездочки ** :
>>> def parrot(voltage, state='a stiff', action='voom'): . print("-- This parrot wouldn't", action, end=' ') . print("if you put", voltage, "volts through it.", end=' ') . print("E's", state, "!") . >>> d = "voltage": "four million", "state": "bleedin' demised", "action": "VOOM"> >>> parrot(**d) # -- This parrot wouldn't VOOM if you put four million volts through it. E's bleedin' demis
- символом * — распаковывают последовательности в качестве элементов которых одно значение (списки, кортежи, множества)
- два символа ** — распаковывают последовательности в качестве элементов которых имеется ключ и значение (словари)
Примеры распаковки списков и словарей с аргументами для функции:
date_inf = 'year': "2020", 'month': "12", 'day': "06"> f_name = " - - .txt".format(**date_inf) print(f_name) # 2020-12-06.txt fruits = ['lemon', 'orange', 'banana', 'tomato'] print(*fruits) # lemon orange banana tomato
Распаковку аргументов можно использовать несколько раз в функции:
date_info = 'year': "2020", 'month': "01", 'day': "01"> track_info = 'artist': "Beethoven", 'title': 'Symphony No 5'> filename = " - - - - .txt".format(**date_info, **track_info) print(filename) # 2020-01-01-Beethoven-Symphony No 5.txt
fruits = ['lemon', 'orange', 'banana', 'tomato'] first, second, *orher = fruits print(orher) # ['banana', 'tomato'] first, *orher = fruits print(orher) # ['orange', 'banana', 'tomato'] first, *middle, last = fruits print(middle) # ['orange', 'banana']
- КРАТКИЙ ОБЗОР МАТЕРИАЛА.
- Функции это объекты
- Функции могут иметь атрибуты
- Функции могут храниться в структурах данных
- Функции могут быть вложенными
- Передача функции в качестве аргумента другой функции
- Область видимости переменных функции
- Операторы global и nonlocal
- Параметры (аргументы) функции
- Ключевые аргументы в определении функции Python
- Значение аргумента по умолчанию в функциях Python
- Варианты передачи аргументов в функцию Python
- Переменные аргументов *args и **kwargs в функции Python
- Распаковка аргументов для передачи в функцию Python
- Как оцениваются аргументы при вызове функции?
- Строгие правила передачи аргументов в функцию Python
- Инструкция return
- Анонимные функции (lambda-выражения)
- Строки документации в функциях Python
- Рекурсия
- Замыкания в функциях Python
- Перегрузка функций
Распаковка словаря аргументов в функции
Распаковка GIF изображения, генерация словаря по LZW алгоритму
Помогите пожалуйста, цель расшифровать картинку и получить массив пикселей в готовом виде. но чтоб.
Странное расположение в памяти аргументов функции с неизвестным количество аргументов
Не могу понять, почему такая программа не работает, выдавая segmentation fault после распечатки.

Выполнить расчет функции от двух аргументов при заданных законах изменения аргументов
Выполнить расчет функции от двух аргументов при заданных законах изменения аргументов. Все значения.
Выполнить расчет функции от двух аргументов при заданных законах изменения аргументов
Выполнить расчет функции от двух аргументов при заданных законах изменения аргументов. Все значения.
![]()
5890 / 3348 / 1034
Регистрация: 03.11.2009
Сообщений: 9,977
а версия питона?
Регистрация: 26.05.2015
Сообщений: 19
![]()
5890 / 3348 / 1034
Регистрация: 03.11.2009
Сообщений: 9,977
а кол-во элементов в словаре большое или изменяемое?
Регистрация: 26.05.2015
Сообщений: 19
Большое количество
![]()
5890 / 3348 / 1034
Регистрация: 03.11.2009
Сообщений: 9,977
Сообщение от 3N4 
Большое количество
мы говорим о десятках, сотнях или тысячах?
2740 / 2339 / 620
Регистрация: 19.03.2012
Сообщений: 8,830
3N4, Зачем тебе это? Что мешает из словаря дергать значения? То, что ты хочешь это порнография.
Сообщение от 3N4 
Нельзя переменные называть именами стандартных типов.
Регистрация: 26.05.2015
Сообщений: 19
Про название стандартными значениями я знаю.
Порядка 50 значений.
Нужно это для того, чтобы не писать конструкции вида:
a = d[arg_name]
2740 / 2339 / 620
Регистрация: 19.03.2012
Сообщений: 8,830
Сообщение от 3N4 
Нужно это для того, чтобы не писать конструкции вида:
a = d[arg_name]
Ты хочешь не явно создавать переменные в области видимости функции это не правильный подход и может влиять как на производительность, так и на качество кода + я не вижу ни какой большой в этом необходимости (если она все же есть, то расскажи нам о ней).
P.S автоматическое создание атрибутов класса и создание переменных не явно это очень разные вещи и если 1 приемлемо, то второе нет.
![]()
5890 / 3348 / 1034
Регистрация: 03.11.2009
Сообщений: 9,977
Сообщение от 3N4 
Порядка 50 значений.
Как по мне, обращение через ключи словаря — совершенно необременительная задача, но в крайнем случае, всегда можно сделать функцию с 50 параметрами, не красиво, но сделает, то что вам нужно.
Регистрация: 26.05.2015
Сообщений: 19
А чем это неверно??
Сначала я написал эти функции, как функции классов.
Но там математические формулы и приставка везде .self делает код вообще нечитабельным.
А от .self избавиться нельзя никак же.
2740 / 2339 / 620
Регистрация: 19.03.2012
Сообщений: 8,830
Сообщение от 3N4 
А чем это неверно??
Сообщение от alex925 
это не правильный подход и может влиять как на производительность, так и на качество кода
Я уже как бы написал
Сообщение от 3N4 
Но там математические формулы и приставка везде .self делает код вообще нечитабельным.
Не видел такой ситуации ни разу
Регистрация: 26.05.2015
Сообщений: 19
Позже выложу пример кода.
Жаль, что в питоне нет аналога «with self» как в VBA например.
Чтобы перед именем атрибута ставить только точку «.attr», без написания «self»
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
Помогаю со студенческими работами здесь
При запуске tomcat должна была произойти распаковка war-файла, но распаковка не происходит
Здравствуйте! Такая проблема..экспортировал из eclipse в war-файл в папку webapps. При запуске.

Можно ли наращивать количество аргументов функции? Можно ли вернуть количество аргументов функции?
К примеру есть примитивная запись int Funk(bool Er,int q1,int q2,int q3) В.
Вычислить значение функции и вывести на печать значения функции и аргументов
Уважаемые программисты, Я новенький на вашем форуме, так что извините, если что не так. Помогите.
Рекурсивные функции и функции с переменным числом аргументов
Напишите программу вычисления значения определенного интеграла при a=4, n=6:
Реализовать функции словаря
Помогите немножко изменить программу! Нужно реализовать в виде отдельных функций – вывод на.
Из словаря создается объект, именами атрибутов которого будут ключи словаря
Из словаря создается объект, именами атрибутов которого будут ключи словаря, а значениями -.
Операторы * и ** в Питоне. Что это и как использовать
Операторы (operators) * и ** встречаются в питоне очень часто. Иногда они немного непонятны и новичкам, и опытным ребятам, переходящим на питон с ряда других языков программирования (в которых операторы могут использоваться немного иначе). Статья известного питон-коуча Трея Ханнера (Trey Hunner), который помогает девелоперам расширять свои знания. Дата написания статьи: 10.11.2018.
Функционал операторов * и ** развивается уже много лет. Я хочу рассмотреть все способы их использования по состоянию на текущий момент. Буду указывать, что конкретно работает только в современных версиях питона. Поэтому, если вы изучали операторы * и ** еще во времена питона 2 (Python 2), советую хотя бы проглядеть данную статью, потому что в питоне 3 (Python 3) этим операторам добавили много новых возможностей.
Если вы начали изучать питон недавно и еще не освоили аргументы ключевых слов (keyword arguments; также известные как именованные аргументы, named arguments), предлагаю сперва прочитать мою статью про аргументы ключевых слов в питоне.
Что мы обсуждать не будем
В данной статье, говоря про операторы * и **, я имею в виду операторы-префиксы (prefix operators), а не инфиксы (infix). То есть, функции умножения и возведения в степень не входят в тему статьи.
Тогда про что же мы говорим
Мы говорим про операторы-префиксы * и **, которые используются перед переменной (variable). Например:
>>> numbers = [2, 1, 3, 4, 7]
>>> more_numbers = [*numbers, 11, 18]
>>> print(*more_numbers, sep=’, ‘)
2, 1, 3, 4, 7, 11, 18
В данном коде можно увидеть два способа использования оператора *. Оператор ** отсутствует.
В сферу применения рассматриваемых операторов входит:
1. Операторы * и **: передача аргументов в функцию.
2. Операторы * и **: захват аргументов, переданных в функцию.
3. Оператор *: принятие аргументов, содержащих только ключевые слова.
4. Оператор *: захват элементов во время распаковки кортежа (tuple).
5. Оператор *: распаковка итерируемых объектов в списке или кортеже.
6. Оператор **: + распаковка словарей в других словарях.
Даже если вам кажется, что вы освоили все эти способы, позволяющие использовать операторы * и **, рекомендую посмотреть на все нижеприведенные блоки кода, чтобы убедиться, что они все вам знакомы. Последние несколько лет разработчики ядра питона продолжают добавлять этим операторам новые возможности, поэтому какие-то из новых применений можно проглядеть.
Операторы * и ** при распаковке во время вызова функции
При вызове функции оператор * можно задействовать для распаковки итерируемого объекта в аргументах, введенных для вызова:
>>> fruits = [‘lemon’, ‘pear’, ‘watermelon’, ‘tomato’]
>>> print(fruits[0], fruits[1], fruits[2], fruits[3])
lemon pear watermelon tomato
>>> print(*fruits)
lemon pear watermelon tomato
В строке print(*fruits) производится вызов всех элементов списка fruits в функции print. Они становятся отдельными аргументами. При этом нам даже не надо знать, сколько всего аргументов окажется в списке.
В данном примере оператор * – не просто синтактический выверт (syntactic sugar). Без * отправить все элементы конкретного итерируемого объекта в качестве отдельных аргументов было бы невозможно (это не касается списков с сфиксированной длиной).
Еще один пример:
def transpose_list(list_of_lists):
return [
list(row)
for row in zip(*list_of_lists)
]
В данном случае мы принимаем список со списками в качестве элементов и возвращаем «преобразованный» список со списками:
>>> transpose_list([[1, 4, 7], [2, 5, 8], [3, 6, 9]])
[[1, 2, 3], [4, 5, 6], [7, 8, 9]]
Функционал оператора ** примерно такой же, просто он применяется к аргументам ключевых слов. Он позволяет нам взять словарь, содержащий пары из ключей и значений, и распаковать его в аргументы ключевых слов при вызове функции.
>>> date_info = <'year': "2020", 'month': "01", 'day': "01">
>>> filename = «—.txt».format(**date_info)
>>> filename
‘2020-01-01.txt’'year':>
Скажу из своего опыта. Оператор ** не часто используется для распаковки аргументов ключевых слов при вызове функции. Чаще всего я вижу такие примеры при работе с наследованием: вызовы super() часто включают в себя оба оператора.
Операторы * и ** можно использовать неоднократно при вызове функции. Данная возможность появилась в питоне 3.5. Иногда это может оказаться очень уместным:
>>> fruits = [‘lemon’, ‘pear’, ‘watermelon’, ‘tomato’]
>>> numbers = [2, 1, 3, 4, 7]
>>> print(*numbers, *fruits)
2 1 3 4 7 lemon pear watermelon tomato
Неоднократное использование ** выглядит примерно так же:
Однако не нужно терять бдительности при неоднократном использовании операторов * и **. Неоднократное указание одного и того же аргумента ключевых слов не допускается в функциях питона. Поэтому, если использовать ** для словарей, то ключи должны быть уникальными. В противном случае возникнет исключение.
Операторы * и ** при упаковке аргументов, переданных функции
При определении тела функции можно использовать оператор *, чтобы захватывать неограниченное количество позиционных аргументов, переданных этой функции. Они оформляются в кортеж.
from random import randint
def roll(*dice):
return sum(randint(1, die) for die in dice)
Данная функция принимает любое количество аргументов.
>>> roll(20)
18
>>> roll(6, 6)
9
>>> roll(6, 6, 6)
8
Функции питона print и zip принимают любое количество позиционных аргументов. Такое использование оператора * при упаковке аргументов позволяет нам создавать свои функции, которые (аналогично print и zip) принимают любое количество аргументов.
Кроме того, для оператора ** в данном вопросе предусмотрена еще одна возможность: его можно использовать при определении тела функции, позволяющей захватить в словарь любые аргументы ключевых слов, переданные этой функции:
def tag(tag_name, **attributes):
attribute_list = [
f’=»»‘
for name, value in attributes.items()
]
return f» >»
В данном месте ** захватывает в словарь аргументы ключевых слов, которые мы передаем данной функции. Впоследствии аргументы атрибутов (attributes) данной функции смогут на него ссылаться.
>>> tag(‘a’, href=»http://treyhunner.com»)
>>> tag(‘img’, height=20, width=40, src=»https://kirill-sklyarenko.ru/face.jpg»)
Позиционные аргументы, содержащие аргументы только из ключевых слов
питон 3 ввел специальный синтаксис для передачи аргументов, содержащих только ключевые слова, в функцию. Они представляют собой такие аргументы функции, которые можно определить только с помощью синтаксиса для ключевых слов. Это означает, что их нельзя определить позиционно.
Чтобы принимать аргументы, содержащие только ключевые слова, мы можем поместить именованные аргументы после оператора * при определении тела функции:
def get_multiple(*keys, dictionary, default=None):
return [
dictionary.get(key, default)
for key in keys
]
Данную функцию можно использовать так:
Аргументы dictionary и default поставлены после *keys. То есть, их можно только в качестве аргументов ключевых слов. Если мы попытаемся определить их позиционно, то увидим ошибку:
>>> fruits = <'lemon': 'yellow', 'orange': 'orange', 'tomato': 'red'>
>>> get_multiple(‘lemon’, ‘tomato’, ‘squash’, fruits, ‘unknown’)
Traceback (most recent call last):
+ File «», line 1, in
TypeError: get_multiple() missing 1 required keyword-only argument: ‘dictionary’'lemon':>
Данное поведение внедрено в питон с помощью предложения PEP 3102.
Аргументы, содержащие только ключевые слова и не содержащие позиционные аргументы
Аргументы, содержащие только ключевые слова, – неплохое средство. Но что если вы хотите требовать ввода аргументов, содержащих только ключевые слова, не захватывая неограниченное количество позиционных аргументов?
питон позволяет сделать это с помощью немного странного синтаксиса, когда оператор * как бы сам по себе:
def with_previous(iterable, *, fillvalue=None):
«»»Yield each iterable item along with the item before it.»»»
previous = fillvalue
for item in iterable:
yield previous, item
previous = item
Данная функция принимает аргумент, содержащий итерируемый объект (iterable). Его можно определить позиционно (то есть, первым) или с помощью названия и аргумента fillvalue, который входит в число аргументов, допускающих только ключевые слова. Это означает, что мы можем вызвать функцию with_previous вот так:
>>> list(with_previous([2, 1, 3], fillvalue=0))
[(0, 2), (2, 1), (1, 3)]
>>> list(with_previous([2, 1, 3], 0))
Traceback (most recent call last):
File «», line 1, in
TypeError: with_previous() takes 1 positional argument but 2 were given
Данная функция принимает два аргумента. Один из них, fillvalue, обязательно определяется как аргумент, содержащий ключевое слово.
Обычно я использую аргументы, допускающие только ключевые слова, при захвате неопределенного количества позиционных аргументов. Но иногда я использую данную возможность оператора *, чтобы форсировать исключительно позиционное определение аргумента.
На самом деле, данный подход используется встроенной функцией питона sorted. Если посмотреть справку для sorted, можно увидеть следующее:
>>> help(sorted)
Help on built-in function sorted in module builtins:
sorted(iterable, /, *, key=None, reverse=False)
Return a new list containing all items from the iterable in ascending order.
A custom key function can be supplied to customize the sort order, and the reverse flag can be set to request the result in descending order.
Пример использования оператора * как самого по себе прямо в документации по аргументам функции sorted.
Операторы * и ** при распаковке кортежа
Дополнительно к вышенаписанному, в питоне 3 добавлен новый способ применения *, который некоторым образом связан с вышеописанными возможностями этого оператора при определении тела функции и при вызове функции.
Оператор * теперь можно использовать при распаковке кортежа:
>>> fruits = [‘lemon’, ‘pear’, ‘watermelon’, ‘tomato’]
>>> first, second, *remaining = fruits
>>> remaining
[‘watermelon’, ‘tomato’]
>>> first, *remaining = fruits
>>> remaining
[‘pear’, ‘watermelon’, ‘tomato’]
>>> first, *middle, last = fruits
>>> middle
[‘pear’, ‘watermelon’]
Если вы задаете себе вопрос: как же мне использовать это в своем коде, посмотрите примеры в моей статье про распаковку кортежей в питоне. В этой статье я показал, каким образом такое использование оператора * может, в некоторых случаях, стать альтернативой для срезания последовательностей (sequence slicing).
Обычно во время своих лекций об операторе * я говорю, что можно использовать только одно выражение с ним в отдельном вызове многократного присвоения (multiple assignment). Технически это некорректно, потому что можно его использовать два раза при вложенной распаковке (nested unpacking). Данный вопрос я рассмотрел подробно в статье про распаковку кортежей.
>>> fruits = [‘lemon’, ‘pear’, ‘watermelon’, ‘tomato’]
>>> ((first_letter, *remaining), *other_fruits) = fruits
>>> remaining
[‘e’, ‘m’, ‘o’, ‘n’]
>>> other_fruits
[‘pear’, ‘watermelon’, ‘tomato’]
Правда, я никогда не встречал хорошего примера такого использования. Не думаю, что стал бы его рекомендовать, даже если бы удалось найти. Он выглядит немного непонятно.
Данная возможность добавлена в питон на основе предложения PEP 3132. Следует отметить, что оно не относится к очень длинным.
Операторы * и ** в литерале списка
В питоне 3.5 добавлено очень много возможностей, связанных с оператором *, на основе предложения PEP 448. Одной из самых заметных новых возможностей стало использование * для вывода итерируемого объекта в новый список.
Допустим, у вас есть функция, которая принимает любые последовательности и возвращает список, содержащий каскад из последовательности и ее реверсивного варианта:
def palindromify(sequence):
return list(sequence) + list(reversed(sequence))
Данная функция должна пару раз провести конвертацию в список, чтобы объединить списки и вернуть результат. Начиная с питона 3.5, мы можем, вместо вышеприведенного примера, написать следующее:
def palindromify(sequence):
return [*sequence, *reversed(sequence)]
В данном коде больше нет нескольких ненужных вызовов списков. Поэтому он стал эффективнее и лучше читается.
def rotate_first_item(sequence):
return [*sequence[1:], sequence[0]]
Данная функция возвращает новый список, в котором первый элемент переданного списка (или другой последовательности) перенесен в конец нового списка.
Это очень удачная возможность, позволяющая с помощью оператора * объединять итерируемые объекты различных типов. Оператор * работает с любыми итерируемыми объектами, а оператор + работает только с определенными последовательностями, при чем все из объединяемых должны быть одного типа.
Отмечу, что данная возможность не ограничивается только созданием списков. Мы можем выводить итерируемые объекты в новые кортежи или множества (set):
Обратите внимание, что последняя строка принимает список и генератор (generator), а потом выводит их в новое множество. Перед появлением этой возможности для оператора * было непросто сделать это в одну строку кода. Разумеется, способ сделать это существовал, но его было непросто вспомнить или обнаружить:
>>> set().union(fruits, uppercase_fruits)
Оператор ** в литерале словаря
Помимо вышеприведенного на основе предложения PEP 448 в функционал ** добавлен вывод пар ключ/значение (key/value) из словаря в новый словарь:
>>> date_info =
>>> track_info =
>>> all_info = <**date_info, **track_info>
>>> all_info
Про это я написал еще одну статью. Сейчас ее можно найти под новым названием про идиоматический способ сливать словари в питоне. Данную возможность можно использовать не только для сливания двух словарей. Например, можно скопировать словарь, параллельно добавляя в него новые значения:
>>> date_info =
>>> event_info = <**date_info, 'group': "Python Meetup">
>>> event_info
Еще можно скопировать или слить словари, переписывая определенные значения:
>>> event_info =
>>> new_info = <**event_info, 'day': "14">
>>> new_info
Операторы * и ** обладают немалыми возможностями в питоне
В питоне операторы * и ** – не просто синтактический выверт. Некоторые из их возможностей реализуются и другими средствами, но доступные альтернативы обычно более громоздкие и потребляют больше ресурсов. Кроме того, некоторые элементы в функционале этих операторов попросту не доступны без их использования. Например, без помощи * невозможно передать в функцию неопределенное количество позиционных аргументов.
Прочитав обо всех возможностях * и **, вы, возможно, удивитесь названиям, под которыми используются эти странные операторы. К сожалению, для них нет лаконичных названий. Я слышал, как * называли оператором для упаковки и распаковки. Еще слышал, как его называли «splat» (это из мира Руби) и просто звездой.
Чаще всего я называю их звездой (star) и двойной звездой (double star) (или звездой-звездой (star star)). В данном случае разделения с их функциями как инфиксов не проводится (речь идет про операции умножения и возведения в степень). Но обычно из контекста очевидно, о чем идет речь, про префиксы или инфиксы.
Если вы не понимаете операторы * и ** или боитесь не запомнить все их возможности, не нужно беспокоиться. Способов использования много, и запоминать каждую конкретную возможность для каждого из них не так важно. Лучше будет осознать, в каких случаях к ним можно обратиться. Предлагать использовать данную статью как чек-лист или создать свой чек-лист, который поможет вам использовать операторы * и ** в питоне.
- перевод с английского
- python
- операторы
Во что распаковывается словарь Python
@and_noob нет, это и есть чёткая синтаксическая конструкция, описанная в документации. См. мой ответ, там есть ссылка.
5 дек 2019 в 14:12
2 ответа 2
Сортировка: Сброс на вариант по умолчанию
Вы верно предположили — всё зависит от контекста, давайте же рассмотрим это детальнее.
Примечание: Я использую Python 3.8 для испытаний
Создание словаря с помощью литералов
Рассмотрим для того, чтобы понять отличия в других ситуациях.
Это самый привычный способ, выглядит это так:
В данном примере словарь будет создан вызовом команды BUILD_CONST_KEY_MAP, которая является специализированной версией BUILD_MAP. Описание самое обыкновенное, не будем заострять на этом внимание.
Создание словаря с помощью распаковки в литералах
Этот способ отличается от первого. Главное, что нужно понять — это не имеет никакого отношения к именованным аргументам. Это специализированный способ. Python вызовет команду BUILD_MAP_UNPACK, чтобы осуществить такое создание. Описание команды гласит:
Берёт count словарей из стека, объединяет их в один словарь, и помещает результат в стек. Осуществляет распаковку словарей в словарь вида <**x, **y, **z>.
Новое в версии 3.5.
Примечание: Вольный перевод. Sorry for my English 🙂
Распаковка в конструктор класса
x = d = dict(**x)
Python создаст кортеж из словаря, используя команду BUILD_TUPLE, а затем вызовет CALL_FUNCTION_EX, которая в свою очередь по необходимости может вызвать BUILD_MAP_UNPACK_WITH_CALL. Выдержка из описания последней команды гласит:
Это похоже на BUILD_MAP_UNPACK, но используется для f(**x, **y, **z) синтаксиса вызова.
Примечание: Вольный перевод. Sorry for my English 🙂
Распаковка словаря в именованные аргументы
def f(a, b): print(a) x = f(**x)
Процесс абсолютно аналогичен варианту выше. В итоге можно сказать, что синтаксис ** в приведённых Вами примерах будет работать по-разному, и команды, которые он порождает, сильно отличаются.
Отслеживать
ответ дан 5 дек 2019 в 14:51
18.4k 5 5 золотых знаков 24 24 серебряных знака 48 48 бронзовых знаков
Есть несколько разных синтаксисов для создания словаря.
Вариант 1: литерал
Инициализация словаря через литерал, элементы описываются парами ключ: значение через запятую:
Здесь и ключ, и значение – нормальные объекты Питона, поэтому ключ-имя должно быть строкой к кавычках (ну или другим hashable объектом).
Вариант 2: конструктор
Можно создать словарь через конструктор (который можно считать обычной функцией), обращаясь к классу:
dict(a=1, b=2)
В неё мы передаём содержимое словаря через именованные аргументы. При этом, часть до знака = является особой лексемой (похоже на переменные) и переводится в строку уже внутри, при создании словаря, кавычки тут неуместны.
function(**d1) – это распаковка элементов словаря в именованные (keyword) аргументы функции. Это встроенный функционал языка для передачи позиционных и именованных аргументов извне. Например, выражение func(**) эквивалентно func(type=’Event’) – только словарь аргументов можно ещё где-то отдельно создавать, модифицировать, передавать, что бывает крайне полезно.
Поэтому, в конструктор словаря (как в обычную функцию) мы можем передать именованные аргументы из другого словаря, в итоге скопировав его содержимое:
d2 = dict(**d1)
Вариант 3: comprehension
Есть ещё comprehension синтаксис, который позволяет лаконично создавать одни итерируемые объекты из других, например:
t = (3, 14, 15) d = d1 = d2 =
Насчёт выражения d3 = <**d1>точно не скажу, возможно это тоже comprehension, возможно вариант литерала, а возможно отдельный синтаксис; но суть понятна, тот же dict(**d1) .
Выражение неправильно потому, что ему не соответствует никакой корректной синтаксической конструкции. field=. можно писать лишь в вызове функций, а внутри фигурных скобок ожидается только что-то из вариантов выше.
Поначалу это всё может немного путать, но не переживайте, так у всех, просто используйте те способы, которые подходят под конкретную задачу. C опытом в голове всё уляжется, а навыки выстроятся в цельную картинку 😉