Передача словаря функции в качестве параметров ключевого слова

Я хотел бы вызвать функцию в Python, используя словарь.

Вот код:

d = dict(param='test')

def f(param):
    print(param)

f(d)

Это печатает {'param': 'test'}, но я бы хотел просто распечатать test.

Я бы хотел, чтобы он работал аналогичным образом для большего количества параметров:

d = dict(p1=1, p2=2)
def f2(p1, p2):
    print(p1, p2)
f2(d)

Это возможно?

Как подобрать выигрышные акции с помощью анализа и визуализации на Python
Как подобрать выигрышные акции с помощью анализа и визуализации на Python
Отказ от ответственности: Эта статья предназначена только для демонстрации и не должна использоваться в качестве инвестиционного совета.
Понимание Python и переход к SQL
Понимание Python и переход к SQL
Перед нами лабораторная работа по BloodOath:
Потяните за рычаг выброса энергососущих проектов
Потяните за рычаг выброса энергососущих проектов
На этой неделе моя команда отменила проект, над которым я работал. Неделя усилий пошла насмарку.
Инструменты для веб-скрапинга с открытым исходным кодом: Python Developer Toolkit
Инструменты для веб-скрапинга с открытым исходным кодом: Python Developer Toolkit
Веб-скрейпинг, как мы все знаем, это дисциплина, которая развивается с течением времени. Появляются все более сложные средства борьбы с ботами, а...
Библиотека для работы с мороженым
Библиотека для работы с мороженым
Лично я попрощался с операторами print() в python. Без шуток.
Эмиссия счетов-фактур с помощью Telegram - Python RPA (BotCity)
Эмиссия счетов-фактур с помощью Telegram - Python RPA (BotCity)
Привет, люди RPA, это снова я и я несу подарки! В очередном моем приключении о том, как создавать ботов для облегчения рутины. Вот, думаю, стоит...
385
0
249 972
4
Перейти к ответу Данный вопрос помечен как решенный

Ответы 4

Вот и все - работает как и любая другая итерация:

d = {'param' : 'test'}

def f(dictionary):
    for key in dictionary:
        print key

f(d)

Похоже, что люди голосуют против этого, поскольку он отвечает на исходный вопрос, а не на перефразированный вопрос. Я предлагаю просто удалить этот пост сейчас.

dotancohen 10.12.2013 12:00

@dotancohen нет, это никогда не было правильным, он не работает во втором блоке кода, который всегда был с вопросом. Это было воспринято слишком буквально, принт был примером.

Dave Hillier 27.02.2014 01:28

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

Natecat 30.11.2016 04:19
Ответ принят как подходящий

В конце концов разобрался для себя. Все просто, мне просто не хватало оператора ** для распаковки словаря

Итак, мой пример становится:

d = dict(p1=1, p2=2)
def f2(p1,p2):
    print p1, p2
f2(**d)

Если вы хотите, чтобы это помогло другим, вам следует перефразировать свой вопрос: проблема не в передаче словаря, вам нужно было превратить dict в параметры ключевого слова

Javier 02.12.2008 20:28

Стоит отметить, что вы также можете распаковывать списки в позиционные аргументы: f2 (* [1,2])

Matthew Trevor 03.12.2008 02:44

«разыменование»: обычный термин в этом контексте Python - «распаковать». :)

mipadi 02.07.2009 22:05

Это здорово, просто использовал его с argparse / __ dict__, чтобы упростить синтаксический анализ аргументов командной строки непосредственно в параметры для объекта класса.

Horus 14.06.2012 07:47

По какой причине мы хотели бы распаковать словарь при передаче его в качестве аргумента функции?

Mona Jalal 30.05.2016 09:07

@MonaJalal Чтобы передать его другой функции, которая принимает, например, **kwargs; он будет ожидать распакованный список аргументов, а не просто словарь аргументов.

Thomas 08.10.2016 13:47

@MonaJalal Это может быть полезно, если вы хотите сделать что-то вроде ast.literal_eval(someText), который мог бы преобразовать someText в словарь; затем вы можете распаковать его в метод (и someText можно предварительно проанализировать для лучшего соответствия ключевым словам в методе, если вам нужны ключевые слова-псевдонимы или что-то подобное). Таким образом, это был бы один из способов разрешить ввод данных (выполняемый для запуска методов), когда он не требует нескольких форм, полей, щелчков мышью и т. д., Без постоянного редактирования самих файлов .py (и это один пример, возможно, бесчисленное множество, где распаковка словаря могла бы быть полезной).

Brōtsyorfuzthrāx 18.08.2017 08:38

@ Дэйв, как этот param преобразуется в 'param', я имею в виду, как имя переменной преобразуется в строку :-))

R__raki__ 19.07.2019 14:18

Это вопрос @ user2728397?

Dave Hillier 19.07.2019 16:12

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

R__raki__ 20.07.2019 10:20

В Python это называется «распаковкой», и вы можете найти немного об этом в руководство. Я согласен с тем, что документация об этом отстойна, особенно из-за того, насколько она фантастически полезна.

Лучше скопировать соответствующее содержание ссылки в свой ответ, чем полагаться на то, что ссылка доживет до конца времени.

Richard 27.07.2014 00:06

@Richard, это глубокое философское мнение о сети, с которым я не мог не согласиться более искренне! Увы, мне не хватает места на этом поле, чтобы поделиться своим замечательным доказательством ...

llimllib 28.07.2014 20:02

@llimllib, тогда мне придется спросить доктора Уайлса!

Richard 28.07.2014 23:49

«Документация об этом отстой», если ваша проблема не в том, чтобы напечатать «Этот попугай не загудит, если вы пропустите через него четыре миллиона вольт. E's bleedin 'кончился» с использованием словаря. В таком случае это прекрасно.

mins 31.01.2021 18:00
In[1]: def myfunc(a=1, b=2):
In[2]:    print(a, b)

In[3]: mydict = {'a': 100, 'b': 200}

In[4]: myfunc(**mydict)
100 200

Несколько дополнительных деталей, которые может быть полезно знать (вопросы, которые у меня возникли после прочтения этого, и я пошел и протестировал):

  1. Функция может иметь параметры, которые нет включены в словарь
  2. Вы можете нет переопределить параметр, который уже есть в словаре
  3. Словарь может иметь параметры нет, которых нет в функции.

Примеры:

Номер 1: Функция может иметь параметры, не входящие в словарь

In[5]: mydict = {'a': 100}
In[6]: myfunc(**mydict)
100 2

Номер 2: Вы не можете переопределить параметр, который уже есть в словаре

In[7]: mydict = {'a': 100, 'b': 200}
In[8]: myfunc(a=3, **mydict)

TypeError: myfunc() got multiple values for keyword argument 'a'

Число 3: В словаре не может быть параметров, которых нет в функции.

In[9]:  mydict = {'a': 100, 'b': 200, 'c': 300}
In[10]: myfunc(**mydict)

TypeError: myfunc() got an unexpected keyword argument 'c'

Как указано в комментариях, решением Цифра 3 является фильтрация словаря на основе аргументов ключевого слова, доступных в функции:

In[11]: import inspect
In[12]: mydict = {'a': 100, 'b': 200, 'c': 300}
In[13]: filtered_mydict = {k: v for k, v in mydict.items() if k in [p.name for p in inspect.signature(myfunc).parameters.values()]}
In[14]: myfunc(**filtered_mydict)
100 200

Другой вариант - принять (и проигнорировать) дополнительные kwargs в вашей функции:

In[15]: def myfunc2(a=None, **kwargs):
In[16]:    print(a)

In[17]: mydict = {'a': 100, 'b': 200, 'c': 300}

In[18]: myfunc2(**mydict)
100

Обратите внимание, что вы можете использовать позиционные аргументы и списки или кортежи так же, как kwargs, вот более сложный пример, включающий как позиционные аргументы, так и аргументы ключевого слова:

In[19]: def myfunc3(a, *posargs, b=2, **kwargs):
In[20]:    print(a, b)
In[21]:    print(posargs)
In[22]:    print(kwargs)

In[23]: mylist = [10, 20, 30]
In[24]: mydict = {'b': 200, 'c': 300}

In[25]: myfunc3(*mylist, **mydict)
10 200
(20, 30)
{'c': 300}

Особенно полезно использовать распаковку с print.format. например: 'hello {greeting} {name}'.format( **{'name': 'Andrew', 'greeting': 'Mr'})

Martlark 02.11.2017 03:12

Старый вопрос, но все еще очень актуальный. Спасибо за подробный ответ. Вы знаете, как обойти случай 3? Что означает питонское сопоставление элементов словаря с параметрами функции, когда в словаре больше элементов, чем параметров?

spencer 25.04.2019 17:22

@spencer к ответу добавлено решение.

David Parks 02.05.2019 20:37

@Martlark Используя строки шаблона, это будет примерно так: subst_dict = {'name': 'Andrew','greeting': 'Mr.'} title = 'hello $greeting $name' formatted_title = Template(title).substitute(**subst_dict)

ali14 15.02.2021 20:20

Другие вопросы по теме