基本列表理解具有以下语法
[expression for var in iterable]
当列表理解发生在类内部时,可以在中使用类的属性
iterable。在Python2和Python3中确实如此。
但是,可以
expression在Python2中使用(即访问)该类的属性,但不能在Python3中使用。
(expression for var in iterable)
虽然仍然可以从访问
iterable类属性,但不能从访问类属性
expression。(对于Python2和Python3确实如此)。
可以将其总结如下:
Python2 Python3Can access class attributes--------------------------------------------------list comp. iterable Y Ylist comp. expression Y Ngen expr. iterable Y Ygen expr. expression N Ndict comp. iterable Y Ydict comp. expression N N
(在这方面,字典理解的行为与生成器表达式相同。)
现在,这与您的问题有何关系:
在您的示例中
second_d = dict((k,first_d[k]) for k in (2,3))
NameError发生a的原因
first_d是无法从
expression生成器表达式的部分进行访问。
Python2的一种解决方法是将生成器表达式更改为列表理解:
second_d = dict([(k,first_d[k]) for k in (2,3)])
但是,我发现这不是一个非常舒适的解决方案,因为此代码将在Python3中失败。
您可以按照Joel Cornett的建议进行:
second_d = {k: v for k, v in first_d.items() if k in (2, 3)}
因为这用
first_d在dict理解的
iterable而不是
expression部分中。但是,如果
first_d包含许多项目,这可能会遍历比所需更多的项目。没什么,如果
first_d很小的话,这个解决方案可能很好。
通常,可以通过定义可以在类内部或外部定义的辅助函数来避免此问题:
def partial_dict(dct, keys): return {k:dct[k] for k in keys}class Example(object): first_d = {1:1,2:2,3:3,4:4} second_d = partial_dict(first_d, (2,3))class Example2(object): a = [1,2,3,4,5] b = [2,4] def myfunc(A, B): return [x for x in A if x not in B] c = myfunc(a, b)print(Example().second_d)# {2: 2, 3: 3}print(Example2().c)# [1, 3, 5]
函数之所以起作用,是因为它们定义了局部作用域,并且可以从dict理解中访问该局部作用域中的变量。
此处已对此进行了解释,但是我对此并不完全满意,因为它无法解释为什么该
expression部分的行为与
iterable列表理解,生成器表达式或dict理解的部分不同。
因此,我无法(完全)解释 为什么 Python会这样表现,而不能完全解释这就是它的表现方式。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)