Могу ли я передать словарные значения / ввод и ключи для работы - PullRequest
1 голос
/ 12 мая 2009

Я пишу функцию и намереваюсь использовать словарный ключ и его значение в качестве параметров. Например:

testDict={'x':2,'xS':4}

def newFunct(key,testDict['key']):
    newvalue=key+str(testDict['key'])
    return newValue

for key in testDict:
    newValue=newFunct(key,testDict[key])
    print newValue

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

for key in testDict:
    xdixt=testDict[key]
    newValue=newFunct(key,xdixt)

и определите функцию, используя xdixt

но я надеюсь, что есть какой-то трюк, который мне не хватает. Я гуглил и нашел ссылку на распаковку словаря, но это не помогло.

Этот Python действительно классный. Мой вопрос возник из-за того, что я пытаюсь использовать некоторые значения, хранящиеся в словаре, для создания нового каталога. Основываясь на материале, который я прочитал из ответа Стефана, я задумался о том, как обобщить информацию, которую я узнал. В моем имени каталога есть пять разных частей, каждый из которых является результатом обработки значений из myDict. Выражение для создания имени каталога становилось слишком сложным и, на мой взгляд, слишком сложным, чтобы его было легко прочитать. поэтому я подумал, могу ли я использовать тот же подход, чтобы поместить кусочки в список, а затем распаковать их, когда пришло время создать имя каталога, и это сработало!

def createDirectory(myKey,**myDict): 
   pathList=[]
   pathList.append(myDict['subKey1'])
   pathList.append(myDict['subKey2'].lstrip('0'))
   pathList.append(myDict['subKey3'])
   etc  
   myPath=os.path.join(*myList)
   os.makedirs(myPath)
   return(myPath)

Ответы [ 4 ]

7 голосов
/ 12 мая 2009

Это то, что вы хотите?

def func(**kwargs):
    for key, value in kwargs.items():
        pass # Do something

func(**myDict) # Call func with the given dict as key/value parameters

(Подробнее о аргументах ключевых слов см. В документации . Ключи в myDict должны быть строками.)


Редактировать : вы отредактировали свой вопрос, включив в него следующее:

Я думаю, что запись ** перед myDict указывает функции ожидать словарь и распаковывать ключ (первый *) и значение, второй *

Это не правильно. Чтобы понять, что происходит, необходимо учитывать следующее:

  • Функция может иметь несколько формальных параметров (a и b в этом случае):
def f1(a, b): pass
  • Мы можем передать позиционные аргументы такой функции (как в большинстве других языков):
f1(2, 3)
  • Мы также можем передать аргументы ключевых слов :
f1(a=2, b=3)
  • Мы также можем смешать их, , но позиционные аргументы должны стоять первыми :
f1(2, b=3)
f1(a=2, 3)  # SyntaxError: non-keyword arg after keyword arg
  • Существует способ разрешить функции принимать произвольное количество позиционных аргументов, к которому она может обращаться как кортеж (args в этом случае):
def f2(*args): assert isinstance(args, tuple)
  • Теперь мы можем вызывать f2, используя отдельно указанные аргументы, или используя список, содержимое которого сначала должно быть распаковано , используя синтаксис, аналогичный обозначению, используемому для *args:
f2(2, 3)
f2(*[2, 3])
  • Аналогично, может быть принято произвольное количество аргументов ключевого слова:
def f3(**kwargs): pass
  • Обратите внимание, что f3 не запрашивает один аргумент типа dict. Это ожидаемые вызовы:
f3(a=2, b=3)
f3(**{'a': 2, 'b': 3})
  • Все аргументы f3 должны быть названы:
f3(2, 3)  # TypeError: f3() takes exactly 0 arguments (2 given)

Собрав все это вместе и помня, что позиционные аргументы должны стоять первыми, мы можем иметь:

>>> def f4(a, b, *args, **kwargs):
...     print('%r, %r' % (args, kwargs))
... 
>>> f4(2, 3)
(), {}
>>> f4(2, 3, 4, 5)
(4, 5), {}
>>> f4(2, 3, x=4, y=5)
(), {'y': 5, 'x': 4}
>>> f4(2, 3, 4, 5, x=6, y=7)
(4, 5), {'y': 7, 'x': 6}
>>> f4(2, *[3, 4, 5], **{'x': 6, 'y': 7})
(4, 5), {'y': 7, 'x': 6}

Обратите особое внимание на следующие две ошибки:

>>> f4(2)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: f4() takes at least 2 arguments (1 given)
>>> f4(2, 3, a=4)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: f4() got multiple values for keyword argument 'a'

Вторая ошибка должна помочь вам объяснить это поведение:

>>> f4(**{'foo': 0, 'a': 2, 'b': 3, 'c': 4})
(), {'c': 4, 'foo': 0}
2 голосов
/ 12 мая 2009

Не уверен, почему мы вводим kwargs, это намного проще, чем это. Вы сказали, что вы новичок в Python, я думаю, вам просто нужны некоторые основы Python здесь.

def newFunct(key,testDict['key']):

Должно быть:

def newFunct(key, val):

Нет причин использовать какой-либо специальный синтаксис для вашего второго параметра, чтобы указать, что он поступает из словаря. Это просто параметр, вы просто передаёте в него значение из словарного элемента.

Кроме того, как только он входит в функцию, нет смысла относиться к нему особым образом. На данный момент это просто значение. Что означает, что:

newvalue=key+str(testDict[key])

Теперь может быть просто:

newvalue=key+str(val)

Итак, когда вы называете это так (как вы сделали):

newValue=newFunct(key,testDict[key])

testDict [ключ] преобразуется в значение в ключе, которое просто становится "val" в функции.


Альтернативным способом, если вы считаете, что он подходит по какой-либо причине (а это просто полезно знать), вы можете определить функцию следующим образом:

def newFunct(key, testDict):

Опять же, второй параметр - это просто параметр, поэтому мы используем тот же синтаксис, но теперь мы ожидаем, что он будет диктатом, поэтому мы должны использовать его как один:

newvalue=key+str(testDict[key])

(Примечание: в этом случае не ставьте кавычки вокруг «ключа». Мы имеем в виду переменную с именем «ключ», а не ключ с именем «ключ»). Когда вы вызываете функцию, она выглядит так:

newValue=newFunct(key,testDict)

Таким образом, в отличие от первого случая, когда вы просто передаете одну переменную из словаря, вы в этот раз передаете ссылку на весь словарь в функцию.

Надеюсь, это поможет.

0 голосов
/ 13 мая 2009

Из вашего описания похоже, что testDict - это некая глобальная переменная по отношению к функции. Если это так - зачем вам вообще нужно передавать это функции?

Вместо вашего кода:

testDict={'x':2,'xS':4}

def newFunct(key,testDict[key]):
    newvalue=key+str(testDict[key])
    return newValue

for key in testDict:
    newValue=newFunct(key,testDict[key])
    print newValue

Вы можете просто использовать:

testDict={'x':2,'xS':4}

def newFunct(key):
    newvalue=key+str(testDict[key])
    return newValue

for key in testDict:
    newValue=newFunct(key)
    print newValue

Если testDict не входит в глобальную область (что имеет смысл ...), я бы рекомендовал просто передать имя словаря, а не "возиться" со списками аргументов переменной длины в этом случае: *

testDict={'x':2,'xS':4}

def newFunct(key,dictionary):
    newvalue=key+str(dictionary[key])
    return newValue

for key in testDict:
    newValue=newFunct(key,testDict)
    print newValue
0 голосов
/ 12 мая 2009

почему бы вам просто не сделать:

[k + str(v) for k, v in test_dict.iteritems()]

или для py3k:

[k + str(v) for k, v in test_dict.items()]

редактировать

def f(k, v):
    print(k, v)      # or do something much more complicated

for k, v in testDict.items():
    f(k, v)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...