如何使用exec根据Python3中的字典将列表分配给变量?
How to use exec to assign list to variable according to dictionary in Python3?
我想将列表分配给变量,而 list
和 variable
都存储在字典 measurements
中。这是 measurements
的 Python 2 版本,变量较少:
measurements = {'tg': [8.184e+16, 8.345e+16, 8.045e+16, 8.520e+16, 8.322e+16, 7.622e+16, 4.305e+16, 2.203e+16]}
def f():
for key,val in measurements.items():
exec(key + ' = val') in globals(),locals()
print (tg)
f()
但是,如another question中所述,它不适合Python 3。
如果我这样写代码:
measurements = {'tg': [8.184e+16, 8.345e+16, 8.045e+16, 8.520e+16, 8.322e+16, 7.622e+16, 4.305e+16,
2.203e+16]}
def f():
for key,val in measurements.items():
ldict = {}
exec(key + ' = val', globals(),ldict)
key = ldict[key]
# exec(key + ' = val') in globals(),locals()
print (tg)
f()
我收到这个错误:NameError: name 'val' is not defined
ldict = {}
技巧创建了一个替代本地名称空间供在 exec
中使用。这很有用,因为 locals()
返回的字典不会像在 Python 2.
中那样直接写入您的实际本地人
但是替代命名空间 {}
是空的。它不包含您的 locals()
,因此其中没有 val
。尝试使用 ldict = {**locals()}
而不是将本地人的内容复制到替代本地人 ldict
.
请记住,您必须从 ldict 中读取由 exec 创建的所有 "locals"。因此,print(tg)
也不会起作用,因为它只在其中一个替代本地名称空间中分配过。您可能不想在每个循环中都制作一个新的。就 .update()
你提前做的一个。
def f():
ldict = {}
for key,val in measurements.items():
ldict.update(locals())
exec(key + ' = val', globals(),ldict)
key = ldict[key]
# exec(key + ' = val') in globals(),locals()
print (ldict['tg'])
为了性能优化,Python3 中的编译器必须提前知道局部变量的数量和名称。 (这不适用于 globals()
,他们仍然写通。)
如果你事先知道他们,你可以直接从他们那里分配,例如
tg = ldict['tg']
print(tg)
如果您需要多个字典,您可以将字典解压成本地字典,例如
a, b, c = (ldict[key] for key in ['a', 'b', 'c'])
或者您可以将整个字典转储到一个简单的命名空间中,然后使用 .
而不是 []
访问它们。
from types import SimpleNamespace
# ...
ns = SimpleNamespace(**ldict)
print(ns.tg)
您也可以 exec
任何需要新局部变量的代码,因为您可以给 exec
ldict
命名空间。
exec("print(tg)", globals(), ldcit)
我知道您的示例代码可能是原始代码的简化版,但似乎根本不需要 exec
。通常认为使用 exec
是不好的形式,除非你绝对需要它,因为它会混淆静态分析工具并且在运行时编译字符串很慢,特别是如果在这样的循环中重复。
如果必须使用 exec,最好将循环放在 exec 字符串内(使用三重引号),而不是将 exec 调用放在循环内。这样字符串只需要编译一次,而不是每次循环。
measurements = {'tg': [8.184e+16, 8.345e+16, 8.045e+16, 8.520e+16, 8.322e+16, 7.622e+16, 4.305e+16, 2.203e+16]}
def f():
for key,val in measurements.items():
exec('{} = {}'.format(key, val))
print (tg)
local = locals()
for key in measurements.keys():
print 'Key: ', key, ', Value: ', local[key]
f()
python3:
measurements = {'tg': [8.184e+16, 8.345e+16, 8.045e+16, 8.520e+16, 8.322e+16, 7.622e+16, 4.305e+16, 2.203e+16]}
def f():
for key,val in measurements.items():
exec('global {};{} = {}'.format(key, key, val))
print ('tg: ', tg)
vars = globals()
for key in measurements.keys():
print ('Key: ', key, ', Value: ', vars[key])
f()
输出:
[8.184e+16, 8.345e+16, 8.045e+16, 8.52e+16, 8.322e+16, 7.622e+16, 4.305e+16, 2.203e+16]
Key: tg , Value: [8.184e+16, 8.345e+16, 8.045e+16, 8.52e+16, 8.322e+16, 7.622e+16, 4.305e+16, 2.203e+16]
多年后,但我已经意识到您可以(滥用)使用在 class 声明中创建的临时名称空间来获得函数内部的直写 locals() 名称空间。这允许您非常直接地翻译 Python 2 版本:
measurements = {'tg': [8.184e+16, 8.345e+16, 8.045e+16, 8.520e+16, 8.322e+16, 7.622e+16, 4.305e+16, 2.203e+16]}
def f():
class _:
for key,val in measurements.items():
exec(key + ' = val', globals(), locals())
print (tg)
f()
我想将列表分配给变量,而 list
和 variable
都存储在字典 measurements
中。这是 measurements
的 Python 2 版本,变量较少:
measurements = {'tg': [8.184e+16, 8.345e+16, 8.045e+16, 8.520e+16, 8.322e+16, 7.622e+16, 4.305e+16, 2.203e+16]}
def f():
for key,val in measurements.items():
exec(key + ' = val') in globals(),locals()
print (tg)
f()
但是,如another question中所述,它不适合Python 3。 如果我这样写代码:
measurements = {'tg': [8.184e+16, 8.345e+16, 8.045e+16, 8.520e+16, 8.322e+16, 7.622e+16, 4.305e+16,
2.203e+16]}
def f():
for key,val in measurements.items():
ldict = {}
exec(key + ' = val', globals(),ldict)
key = ldict[key]
# exec(key + ' = val') in globals(),locals()
print (tg)
f()
我收到这个错误:NameError: name 'val' is not defined
ldict = {}
技巧创建了一个替代本地名称空间供在 exec
中使用。这很有用,因为 locals()
返回的字典不会像在 Python 2.
但是替代命名空间 {}
是空的。它不包含您的 locals()
,因此其中没有 val
。尝试使用 ldict = {**locals()}
而不是将本地人的内容复制到替代本地人 ldict
.
请记住,您必须从 ldict 中读取由 exec 创建的所有 "locals"。因此,print(tg)
也不会起作用,因为它只在其中一个替代本地名称空间中分配过。您可能不想在每个循环中都制作一个新的。就 .update()
你提前做的一个。
def f():
ldict = {}
for key,val in measurements.items():
ldict.update(locals())
exec(key + ' = val', globals(),ldict)
key = ldict[key]
# exec(key + ' = val') in globals(),locals()
print (ldict['tg'])
为了性能优化,Python3 中的编译器必须提前知道局部变量的数量和名称。 (这不适用于 globals()
,他们仍然写通。)
如果你事先知道他们,你可以直接从他们那里分配,例如
tg = ldict['tg']
print(tg)
如果您需要多个字典,您可以将字典解压成本地字典,例如
a, b, c = (ldict[key] for key in ['a', 'b', 'c'])
或者您可以将整个字典转储到一个简单的命名空间中,然后使用 .
而不是 []
访问它们。
from types import SimpleNamespace
# ...
ns = SimpleNamespace(**ldict)
print(ns.tg)
您也可以 exec
任何需要新局部变量的代码,因为您可以给 exec
ldict
命名空间。
exec("print(tg)", globals(), ldcit)
我知道您的示例代码可能是原始代码的简化版,但似乎根本不需要 exec
。通常认为使用 exec
是不好的形式,除非你绝对需要它,因为它会混淆静态分析工具并且在运行时编译字符串很慢,特别是如果在这样的循环中重复。
如果必须使用 exec,最好将循环放在 exec 字符串内(使用三重引号),而不是将 exec 调用放在循环内。这样字符串只需要编译一次,而不是每次循环。
measurements = {'tg': [8.184e+16, 8.345e+16, 8.045e+16, 8.520e+16, 8.322e+16, 7.622e+16, 4.305e+16, 2.203e+16]}
def f():
for key,val in measurements.items():
exec('{} = {}'.format(key, val))
print (tg)
local = locals()
for key in measurements.keys():
print 'Key: ', key, ', Value: ', local[key]
f()
python3:
measurements = {'tg': [8.184e+16, 8.345e+16, 8.045e+16, 8.520e+16, 8.322e+16, 7.622e+16, 4.305e+16, 2.203e+16]}
def f():
for key,val in measurements.items():
exec('global {};{} = {}'.format(key, key, val))
print ('tg: ', tg)
vars = globals()
for key in measurements.keys():
print ('Key: ', key, ', Value: ', vars[key])
f()
输出:
[8.184e+16, 8.345e+16, 8.045e+16, 8.52e+16, 8.322e+16, 7.622e+16, 4.305e+16, 2.203e+16]
Key: tg , Value: [8.184e+16, 8.345e+16, 8.045e+16, 8.52e+16, 8.322e+16, 7.622e+16, 4.305e+16, 2.203e+16]
多年后,但我已经意识到您可以(滥用)使用在 class 声明中创建的临时名称空间来获得函数内部的直写 locals() 名称空间。这允许您非常直接地翻译 Python 2 版本:
measurements = {'tg': [8.184e+16, 8.345e+16, 8.045e+16, 8.520e+16, 8.322e+16, 7.622e+16, 4.305e+16, 2.203e+16]}
def f():
class _:
for key,val in measurements.items():
exec(key + ' = val', globals(), locals())
print (tg)
f()