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

Скажи, что есть,

foo = 'bar'
d = {'a-key':'a-value'}

А ты хочешь

d = {'a-key':'a-value','foo':'bar'}
e = {'foo':foo}

Я знаю, что вы можете сделать,

d['foo'] = foo

#Either of the following for e
e = {'foo':foo}
e = dict(foo=foo)

Но, чтобы добавить переменную foo к dict, мне пришлось использовать слово foo дважды; один раз, чтобы указать ключ и один раз для его значения.

Мне кажется, расточительно использовать foo дважды. Есть ли более простой способ, которым вы можете сказать python «Добавить эту переменную в словарь с ее именем в качестве ключа и его значением в качестве значения» ?

Ответы [ 7 ]

4 голосов
/ 12 ноября 2009

вы можете сделать что-то вроде этого

def add_dry_foo(d, namespace, fooName):
    d[fooName] = namespace[fooName]

foo = 'oh-foo'
d = {}
add_dry_foo(d, locals(), 'foo')
print d
2 голосов
/ 12 ноября 2009

На самом деле использование foo дважды очень распространено в программах на Python. Он широко используется для передачи аргументов, например

def f(foo, bar):
    g(foo=foo)

Что является специализированным случаем манипуляций со словарем в вашем вопросе.

Я не думаю, что есть способ избежать этого, не прибегая к magic , поэтому я думаю, что вам придется с этим жить.

2 голосов
/ 12 ноября 2009

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

name = 'foo'
d[name] = vars[name]

Я не вижу разницы между вашими d и e случаями: оба устанавливают для 'foo' значение foo.

Становится сложнее, если вы хотите похоронить это в функции:

def add_variable(d, name):
    # blah

потому что тогда он должен использовать inspect, чтобы начать ковыряться в кадрах.

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

d.update(locals())

, который скопирует имена и значения всех локальных переменных в d.

1 голос
/ 12 ноября 2009

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

dict([ (var, locals()[var]) for var in ['foo', 'bar'] ])

или в Python 3.0 это станет возможным:

{ var: locals()[var] for var in ['foo', 'bar'] }

1 голос
/ 12 ноября 2009

Чтобы добавить все локальные переменные в dict, вы можете сделать:

d.update(locals())

То же самое работает для вызовов функций:

func(**locals())

Обратите внимание, что в зависимости от того, где вы находитесь locals(), конечно, может содержать вещи, которые не должны попадать в диктат. Чтобы вы могли реализовать функцию фильтра:

def filtered_update(d, namespace):
    for key, value in namespace.items():
        if not key.startswith('__'):
            d[key] = value

filtered_update(d, locals())

Конечно, философия Python «явный лучше, чем неявный», поэтому обычно я бы прошел лишнюю милю и делал подобные вещи вручную (в противном случае вы должны быть осторожны с тем, что происходит в вашем местном пространстве имен).

0 голосов
/ 03 марта 2011

Мне кажется, что вы говорите о расширение функциональности передачи параметров:

def func(*vars):

предоставляет кортеж упорядоченных значений без ключей

def func(**vars):

предоставляет набор пар ключ-значение, который ДОЛЖНЫ быть переданы как ключ = значение пар.

def func(***vars):

БЫЛО ПРЕДОСТАВИТЬ набор ключей-значений, передается либо явно как ключ = значение , или неявно как ключ (переменная, литералы могут вызвать ошибку без key = )

SO:

(x1,x2,x3) = (1,2,3)
def myfunc(***vars):
  retrun vars
myfunc(x1,x2,x3)
>>> {'x1':1,'x2':2,'x3':3}

Но, конечно, это просто желаемое за действительное ...

0 голосов
/ 12 ноября 2009

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

>>> d = dict()
>>> foo = 'wibble'
>>> def add(d, name):
        d[name] = eval(name)


>>> add(d, 'foo')
>>> d
{'foo': 'wibble'}

Edit: Я должен указать, почему я не рекомендую "eval". Что произойдет, если вы сделаете что-то подобное? (от: http://mail.python.org/pipermail/tutor/2005-November/042854.html)

>>> s = "(lambda loop: loop(loop)) (lambda self: self(self))"
>>> add(d, s)

Traceback (most recent call last):
  File "<pyshell#54>", line 1, in <module>
    add(d, s)
  File "<pyshell#43>", line 2, in add
    d[name] = eval(name)
  File "<string>", line 1, in <module>
  File "<string>", line 1, in <lambda>
  File "<string>", line 1, in <lambda>
  ...
  File "<string>", line 1, in <lambda>
RuntimeError: maximum recursion depth exceeded
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...