Python:返回一个dict的函数,其键是输入参数的名称

Python:返回一个dict的函数,其键是输入参数的名称,python,dictionary,Python,Dictionary,是否可以编写一个函数f,该函数接受任意的混合数据元组: T = 1.0 N = 20 L = 10 args = (T,N,L) f(*args) # or maybe f(T,N,L)? 并作为输出返回: {'T':1.0, 'N':20, 'L':10} 有一个使用local,但是我似乎在将名称传递给函数后丢失了它们。有没有办法防止这种情况?我猜变量是按值传递的,因此它们被视为新对象 跟进:否,这在*args中通常是不可能的。您必须使用关键字参数: >>> def f

是否可以编写一个函数
f
,该函数接受任意的混合数据元组:

T = 1.0
N = 20
L = 10
args = (T,N,L)

f(*args) # or maybe f(T,N,L)?
并作为输出返回:

{'T':1.0, 'N':20, 'L':10}
有一个使用
local
,但是我似乎在将名称传递给函数后丢失了它们。有没有办法防止这种情况?我猜变量是按值传递的,因此它们被视为新对象


跟进:

否,这在
*args
中通常是不可能的。您必须使用关键字参数:

>>> def f(**kwargs):
...  return kwargs
... 
>>> f(T=1.0, N=20, L=10)
{'T': 1.0, 'L': 10, 'N': 20}
keys = ('T', 'N', 'L')
values = (1.0, 20, 10)
d = dict(zip(keys, values))
原因是,
*args
没有为各个参数引入名称;它只为它们的整个列表引入名称
args
。函数无法洞察参数外部的名称(如果有)

当参数的数量固定时,可以使用
局部变量

>>> def g(T, N, L):
...  return locals()
... 
>>> g(T=1.0, N=20, L=10)
{'L': 10, 'T': 1.0, 'N': 20}

(或者显式使用
返回{'T':T,'N':N,'L':L}

在Python中,变量只是附加到值的标签。因此,无法从另一个范围知道调用函数时使用了哪些标签。

是的,据我所知,args是一个列表。要保留标签名称,您需要将dict传递给**kwargs,并使用
local
以显式或编程方式设置名称

你可以这样做:

def filter_locals(caller_locals, *args):
    filtered = {}
    for key in args:
        filtered[key] = caller_locals[key]
    return filtered
然后:


其中func将任意长度的列表处理为kwargs。

必须将键和值作为单独的参数传递:

>>> def f(**kwargs):
...  return kwargs
... 
>>> f(T=1.0, N=20, L=10)
{'T': 1.0, 'L': 10, 'N': 20}
keys = ('T', 'N', 'L')
values = (1.0, 20, 10)
d = dict(zip(keys, values))

在您的代码中,
args=(T,N,L)
行的计算结果为
args=(1.0,20,10)
,变量T,N,L的“名称”被它们的值替换。

您的猜测不幸是错误的,事实上整个问题暴露了对Python名称如何工作的误解

总体而言,Python对象不知道它们的名称。这是完全可以理解的,当您认为您可以轻松地分配<代码> A= B<代码>,现在“代码> A < /COD>和<代码> B<代码>两者都指的是完全相同的对象。Python的“变量”只是指向对象的名称,它们不以任何实际方式包含这些对象。向函数传递参数时,传递的是底层对象,而不是名称。接收函数只是将它们绑定到函数签名中指定的名称,或者,在您的例子中,只是将它们保存在
args
中,而不给它们任何名称


因此,当您询问如何获取对象在不同范围内的名称时,您不能询问对象本身。可能有一种方法可以做到这一点,但它涉及到检查调用帧,我非常怀疑您是否愿意这样做。

使用
globals()
的解决方案。这只在值在模块范围内是唯一的情况下才起作用,因此它是脆弱的-如果有重复项,它将选择指向该值的第一个名称,有些随意。是的,无论如何,你最好不要这样做,而是重新思考这个问题

def f(*names):
    r = {}
    for n in names:
        r[[ name for name in globals() if globals()[name] is n ][0]] = n
    return r

T = 1.0
N = 20
L = 10

print f(T,N,L)
{'T': 1.0, 'L': 10, 'N': 20}

你似乎混淆了这里的概念。其他语言也有变量,但。可能不可能,但当我被证明是错误的(可能是字节码分析或诸如此类的愚蠢行为)时,我会把它作为一个注释。我认为在一些限制条件下,这是可能的,请看我的答案。虽然不健壮,也不值得称赞。然后,当您执行
(T=1.0,N=20,L=10)
时,您将返回到显式描述键名,而不是隐式派生它们。