我有一个方法,可以获取一个列表并返回一个对象
# input a list, returns an object
def map_to_obj(lst):
a_list = f(lst)
return a_list[0] if a_list else None
Run Code Online (Sandbox Code Playgroud)
我想获得一个包含所有未映射的元素的列表None.
像这样:
v_list = [v1, v2, v3, v4]
[map_to_obj(v) for v in v_list if map_to_obj(v)]
Run Code Online (Sandbox Code Playgroud)
但是map_to_obj在列表推导中调用该方法两次似乎并不好.
有没有办法在列表推导中使用局部变量,以便它可以有更好的性能?
或者编译器是否自动优化它?
这就是我想要的:
(sml like)
[let mapped = map_to_obj(v) in for v in v_list if mapped end]
Run Code Online (Sandbox Code Playgroud) 比方说,我想创建的列表ints,它由数字1至10立方体使用Python 只有当立方体是由四个整除.
我写了这个工作线:
cube4 = [x ** 3 for x in range(1, 11) if (x ** 3) % 4 == 0]
Run Code Online (Sandbox Code Playgroud)
我对这行代码的看法是,它计算x的立方体两次.是否有更多pythonic方式来写这条线?或者这是否与列表理解一样好?
编辑 -我的问题旨在集中在如何使用Python的功能和细微差别避免无关的计算,同时仍然保持代码简洁和可读.虽然可能已经找到了解决其他问题的解决方案,但我想确保我知道这个问题的最佳答案,而不仅仅是一个有效的解决方案.
使用下面的示例,我们可以看到x.giveMyNum()将被调用4次 - 3次以检查myNum的值,并且一次构造要返回的列表.您可能希望它只被调用3次,因为它是一个纯函数,它的值不会改变.
列表理解版本:
class test(object):
def __init__(self,myNum):
self.myNum=myNum
def giveMyNum(self):
print "giving"
return self.myNum
q=[test(x) for x in range(3)]
print [x.giveMyNum() for x in q if x.giveMyNum()>1]
Run Code Online (Sandbox Code Playgroud)
我知道你可以做这样的事情来解决它:
ret=[]
for x in q:
k=x.giveMyNum()
if k>1:
ret.append(k)
Run Code Online (Sandbox Code Playgroud)
但有没有办法阻止列表理解中的额外调用?
我不需要保留中间值.
我有一个字符串列表(字符串和列表都可以很大).我想只从列表中的某些元素构建字典.
l = ['aaa 0','bbb 1','ccc 2','ddd 3','abc 1']
wanted = set(['aaa','abc'])
dict([x.split() for x in l if x.split()[0] in wanted])
{'aaa': '0', 'abc': '1'}
Run Code Online (Sandbox Code Playgroud)
可以在不调用split()操作两次的情况下完成吗?
在哈斯克尔,我可以做
Prelude> [(y*3, y+4) | x<-[0..5], let y=x^2]
[(0,4),(3,5),(12,8),(27,13),(48,20),(75,29)]
Run Code Online (Sandbox Code Playgroud)
Python 中的等效项是什么,无需重复幂运算,正如我需要的那样
>>> [((x**2)*3, (x**2)+4) for x in range(5)]
[(0, 4), (3, 5), (12, 8), (27, 13), (48, 20)]
Run Code Online (Sandbox Code Playgroud)
我当然可以用 lambda 模拟 Haskell 代码,但这感觉不太 Pythonic...
>>> [(lambda y: (y*3, y+4))(x**2) for x in range(5)]
Run Code Online (Sandbox Code Playgroud)