在追求一些外观漂亮,功能感强的Python代码时,我想知道如何将一组名称绑定到将函数应用于其当前绑定值的结果。请考虑以下代码:
# preamble
a = [4]
b = [5]
c = [6]
# code
a = len(a)
b = len(b)
c = len(c)
print(a, b, c)
但是,为三个变量中的每一个输入x = len(x)
肯定是多余的,对吗?
我可以重新分配这样的名字:
a, b, c = (len(x) for x in (a, b, c))
...但这也有一些冗余,因为我必须列出a, b, c
两次!
inspect
... 我们可以使用inspect
让事情变得更好:
import inspect
def apply_in_scope(f, v):
parent = inspect.stack()[1].frame.f_globals
for i in v:
parent[i] = f(parent[i])
a = [5]
b = [7, 9]
c = [9, 10, 11, 12]
apply_in_scope(len, ("a", "b", "c"))
print(a, b, c)
...但现在我必须将我的变量名称放在引号中,而不是直接使用它们。问题是when you call a function in Python, the function gets passed a new reference。
稍微更改代码,我们可以对与给定参数匹配的参数进行二次搜索,这非常慢,但我认为有效:
import inspect
def apply_in_scope(f, values):
parent = inspect.stack()[1].frame.f_globals
names = [k for k, v in parent.items() if any(v is x for x in values)]
for name in names:
parent[name] = f(parent[name])
a = [5]
b = [7, 9]
c = [9, 10, 11, 12]
apply_in_scope(len, (a, b, c))
print(a, b, c)
......但我不禁想到必须有更好的方法,或者我错过了一些简单的东西。这在LISP中相当容易,这让我觉得在Python中不需要这么多体操。
(警告:如果多个变量is
具有相同的值,上述解决方案将多次应用该函数!)
编辑:这个问题与how to make a variable number of variables不同,因为问题(1)适用于全局范围,而不适用于本地函数范围,(2)不解决此处提出的重新分配问题的基本元编程问题应用函数。