更简单的方法来创建单独变量的字典?

e-s*_*tis 218 python string variables

我希望能够将变量的名称作为字符串获取,但我不知道Python是否具有那么多的内省功能.就像是:

>>> print(my_var.__name__)
'my_var'
Run Code Online (Sandbox Code Playgroud)

我想这样做因为我有一堆vars我想变成一本字典,如:

bar = True
foo = False
>>> my_dict = dict(bar=bar, foo=foo)
>>> print my_dict 
{'foo': False, 'bar': True}
Run Code Online (Sandbox Code Playgroud)

但我想要比这更自动的东西.

Python中有locals()vars(),所以我想有一种方法.

rlo*_*tun 131

正如unwind所说,这不是你在Python中所做的事情 - 变量实际上是对象的名称映射.

但是,这是尝试这样做的一种方法:

 >>> a = 1
 >>> for k, v in list(locals().iteritems()):
         if v is a:
             a_as_str = k
 >>> a_as_str
 a
 >>> type(a_as_str)
 'str'
Run Code Online (Sandbox Code Playgroud)

  • @ e-satisf我很惊讶你没有把这个答案标记为答案,因为我同意你的评论说*rlotun更接近它的最初"精神",因为它允许发现名字*.此外,S.Lott的答案根本没有回答你的问题...... (16认同)
  • 这个想法有其优点,但请注意,如果两个变量名引用相同的值(例如"True"),则可能会返回一个非预期的变量名. (14认同)
  • 为什么`id(v)== id(a)`而不是`v是a`?对于绑定到多个变量的对象,例如int,字符串和任何类似实现的用户定义类型,这将失败. (14认同)
  • +1.非常巧妙,虽然有点矫枉过正和危险. (6认同)
  • "过度杀伤和危险"......并且使用eval不是吗? (2认同)

kef*_*ich 63

我想这么做很多.这个hack与rlotun的建议非常相似,但它是一个单行,这对我很重要:

blah = 1
blah_name = [ k for k,v in locals().iteritems() if v is blah][0]
Run Code Online (Sandbox Code Playgroud)

Python 3+

blah = 1
blah_name = [ k for k,v in locals().items() if v is blah][0]
Run Code Online (Sandbox Code Playgroud)

  • 请注意,在Python 3中,`iteritems()`被`items()`取代 (10认同)
  • @keflavich我非常喜欢这种方法,现在不时使用它.但是我不能让它在函数内部工作.我想有"更好"的方法来做到这一点,但没有一个像nbubis那样简单.你能在keflavich功能中使用它吗?[这](http://stackoverflow.com/questions/18702402/return-variable-name-from-outside-of-function-as-string-inside-python-function?noredirect=1#comment27554355_18702402)是我问的地方关于这一点的问题. (3认同)

S.L*_*ott 47

你想这样做吗?

dict( (name,eval(name)) for name in ['some','list','of','vars'] )
Run Code Online (Sandbox Code Playgroud)

>>> some= 1
>>> list= 2
>>> of= 3
>>> vars= 4
>>> dict( (name,eval(name)) for name in ['some','list','of','vars'] )
{'list': 2, 'some': 1, 'vars': 4, 'of': 3}
Run Code Online (Sandbox Code Playgroud)

  • **这个答案没有回答问题.***如果你有变量列表,那么"发现"他们的名字是什么意思?*为了避免重复而不是'print('x:'+ x) `一个人可以编写`magic_print(x)`并且输出相同但不编写变量名两次. (240认同)
  • @ e-satisf:要让@ rlotun工作,你必须提供变量列表.如果你有变量列表,那么"发现"他们的名字是什么意思? (7认同)
  • 为什么eval而不是显式使用本地和全局? (4认同)
  • rlotun 更接近它最初的“精神”,因为它允许发现名称。我可以同时使用你的 anwser。或者也许只是用我该死的手打字。有些事情并没有那么自动化...... (2认同)

unu*_*tbu 17

这是一个黑客.它不适用于所有Python实现分发(特别是那些没有traceback.extract_stack.)

import traceback

def make_dict(*expr):
    (filename,line_number,function_name,text)=traceback.extract_stack()[-2]
    begin=text.find('make_dict(')+len('make_dict(')
    end=text.find(')',begin)
    text=[name.strip() for name in text[begin:end].split(',')]
    return dict(zip(text,expr))

bar=True
foo=False
print(make_dict(bar,foo))
# {'foo': False, 'bar': True}
Run Code Online (Sandbox Code Playgroud)

请注意,这个hack很脆弱:

make_dict(bar,
          foo)
Run Code Online (Sandbox Code Playgroud)

(在2行上调用make_dict)将不起作用.

而不是试图生成字典出的价值观 foobar,这将是更更Python生成字典出字符串的变量名 'foo''bar':

dict([(name,locals()[name]) for name in ('foo','bar')])
Run Code Online (Sandbox Code Playgroud)


unw*_*ind 14

这在Python中是不可能的,它实际上没有"变量".Python有名称,同一个对象可以有多个名称.


The*_*iat 10

我认为我的问题将有助于说明为什么这个问题很有用,并且可以更深入地了解如何回答这个问题.我写了一个小函数来对代码中的各种变量进行快速内联检查.基本上,它列出了变量名称,数据类型,大小和其他属性,因此我可以快速发现我所犯的任何错误.代码很简单:

def details(val):
  vn = val.__name__                 #  If such a thing existed
  vs = str(val)
  print("The Value of "+ str(vn) + " is " + vs)
  print("The data type of " + vn + " is " + str(type(val)))
Run Code Online (Sandbox Code Playgroud)

因此,如果您有一些复杂的字典/列表/元组情况,让解释器返回您指定的变量名称会非常有帮助.例如,这是一个奇怪的字典:

m = 'abracadabra'
mm=[]    
for n in m:
  mm.append(n)
mydic = {'first':(0,1,2,3,4,5,6),'second':mm,'third':np.arange(0.,10)}



details(mydic)

The Value of mydic is {'second': ['a', 'b', 'r', 'a', 'c', 'a', 'd', 'a', 'b', 'r', 'a'], 'third': array([ 0.,  1.,  2.,  3.,  4.,  5.,  6.,  7.,  8.,  9.]), 'first': [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]}
The data type of mydic is <type 'dict'>

details(mydic['first'])
The Value of mydic['first'] is (0, 1, 2, 3, 4, 5, 6)]
The data type of mydic['first'] is <type 'list'>

details(mydic.keys())
The Value of mydic.keys() is ['second', 'third', 'first']
The data type of mydic.keys() is <type 'tuple'>

details(mydic['second'][0])
The Value of mydic['second'][0] is a
The data type of mydic['second'][0] is <type 'str'>
Run Code Online (Sandbox Code Playgroud)

我不确定我是否把它放在正确的位置,但我认为这可能会有所帮助.我希望如此.


aqu*_*tle 9

我根据这个问题的答案写了一个简洁实用的小功能.我把它放在这里以防它有用.

def what(obj, callingLocals=locals()):
    """
    quick function to print name of input and value. 
    If not for the default-Valued callingLocals, the function would always
    get the name as "obj", which is not what I want.    
    """
    for k, v in list(callingLocals.items()):
         if v is obj:
            name = k
    print(name, "=", obj)
Run Code Online (Sandbox Code Playgroud)

用法:

>> a = 4
>> what(a)
a = 4
>>|
Run Code Online (Sandbox Code Playgroud)


cdh*_*ann 6

我发现如果你已经有了一个特定的值列表,那就是@S描述的方式.Lotts是最好的; 但是,下面描述的方法很适合在整个代码中添加所有变量和类,而不需要提供变量名称,尽管您可以根据需要指定它们.代码可以扩展为排除类.

import types
import math  # mainly showing that you could import what you will before d

# Everything after this counts
d = dict(globals())

def kv_test(k,v):
    return (k not in d and 
            k not in ['d','args'] and
            type(v) is not types.FunctionType)

def magic_print(*args):
    if len(args) == 0: 
        return {k:v for k,v in globals().iteritems() if kv_test(k,v)}
    else:
        return {k:v for k,v in magic_print().iteritems() if k in args}

if __name__ == '__main__':
    foo = 1
    bar = 2
    baz = 3
    print magic_print()
    print magic_print('foo')
    print magic_print('foo','bar')
Run Code Online (Sandbox Code Playgroud)

输出:

{'baz': 3, 'foo': 1, 'bar': 2}
{'foo': 1}
{'foo': 1, 'bar': 2}
Run Code Online (Sandbox Code Playgroud)


off*_*sof 6

在python 3中,这很容易

myVariable = 5
for v in locals():
  if id(v) == id("myVariable"):
    print(v, locals()[v])
Run Code Online (Sandbox Code Playgroud)

这将打印:

myVariable 5

  • -1.打开一个新的解释器窗口并尝试`for loc in locals()`. (10认同)
  • 这将给出一个错误:RuntimeError:字典在迭代期间改变了大小... (4认同)
  • 但是你可以在list(locals())中为v设置` (2认同)

vvx*_*xii 5

Python3.使用inspect来捕获调用本地命名空间,然后使用此处提供的想法.如前所述,可以返回多个答案.

def varname(var):
  import inspect
  frame = inspect.currentframe()
  var_id = id(var)
  for name in frame.f_back.f_locals.keys():
    try:
      if id(eval(name)) == var_id:
        return(name)
    except:
      pass
Run Code Online (Sandbox Code Playgroud)


Ann*_*nna 5

这是我创建的用于读取变量名称的函数.它更通用,可用于不同的应用程序:

def get_variable_name(*variable):
    '''gets string of variable name
    inputs
        variable (str)
    returns
        string
    '''
    if len(variable) != 1:
        raise Exception('len of variables inputed must be 1')
    try:
        return [k for k, v in locals().items() if v is variable[0]][0]
    except:
        return [k for k, v in globals().items() if v is variable[0]][0]
Run Code Online (Sandbox Code Playgroud)

要在指定的问题中使用它:

>>> foo = False
>>> bar = True
>>> my_dict = {get_variable_name(foo):foo, 
               get_variable_name(bar):bar}
>>> my_dict
{'bar': True, 'foo': False}
Run Code Online (Sandbox Code Playgroud)