Python 用不同的语句列出理解示例
如果我有下一个for循环Python 用不同的语句列出理解示例,python,list-comprehension,Python,List Comprehension,如果我有下一个for循环 a = 0 b = [1,2,3] for x in b: print a + x a = x 是否可以在列表中覆盖它?我的第一次尝试是失败: a = 0 b = [1,2,3] [[print a+x, a=x] for x in b] [[print a+x, a=x] for x in b] ^ SyntaxError: invalid syntax 有很多方法可以把它写成一个理解列表,但是你真的不应该。理解用于
a = 0
b = [1,2,3]
for x in b:
print a + x
a = x
是否可以在列表中覆盖它?我的第一次尝试是失败:
a = 0
b = [1,2,3]
[[print a+x, a=x] for x in b]
[[print a+x, a=x] for x in b]
^
SyntaxError: invalid syntax
有很多方法可以把它写成一个理解列表,但是你真的不应该。理解用于面向表达式的编程,循环用于副作用。有一些方法可以将其作为列表理解来编写,但您确实不应该这样做。理解用于面向表达式的编程,循环用于副作用。在列表理解中不能使用打印。您应该保留for循环。您不能在列表中使用print。你应该保留for循环。正如拉斯曼所说,你真的不应该这样做。使用副作用的疯狂列表理解比行为良好的自足理解更难阅读和理解 但是如果你仍然好奇的话,这里有一个不同的方法。它使用可变的默认功能参数来保存状态
def adder(x, last=[]):
if last == []:
last.append(0)
last[0] += x
return last[0]
b = (1, 2, 3, 4)
print [adder(x) for x in b]
显然,这比for循环更冗长、更难阅读,而且我敢说它的效率也要低得多。而且它依赖于Python的一个特性(可变默认函数参数的行为),这对于新的Python程序员来说并不容易理解(而且许多有经验的Python程序员也不是特别满意)
所以请不要在你的代码中使用这种疯狂
编辑 这里有一些更多的方法可以通过列表理解来做这种坏事 首先,在序列的切片副本上使用
sum
的方法效率极低:
b = (10, 20, 30, 40)
[sum(b[:1+i]) for i in xrange(len(b))]
类似的丑陋,这次使用reduce
。Guido讨厌在最好的时候减少,所以我不想想象他会怎么看待这个怪物
这里还有一些是我不久前设计的,两个使用函数属性保存状态,最后一个使用类保存状态,这可能是最不讨厌的方式
#! /usr/bin/env python
''' Create an accumulator function from a 2 arg function.
Like a cross between map() & reduce().
'''
def acc0(func, v0=0):
def f(v):
f.v = func(f.v, v)
return f.v
f.v = v0
return f
def acc1(func, v0=0):
def f(v, c=None):
if c!=None:
f.v = c
f.v = func(f.v, v)
return f.v
f.v = v0
return f
class acc2(object):
def __init__(self, func, value=0):
self.v = value
self.func = func
def __call__(self, x):
self.v = self.func(self.v, x)
return self.v
def test(acc):
g = acc(lambda u,v: u+v)
print [g(i) for i in xrange(1,12)]
f = acc(lambda u,v: u*v, 1)
print [f(i) for i in xrange(1,12)]
f.v = 10
print [f(i) for i in xrange(1,12)]
f.v = 1
print [f(i) for i in xrange(1,15)]
f.v = 2
print [f(i) for i in xrange(1,12)]
g.v = 0
print [g(i) for i in xrange(1,12)]
g.v = 100
print [g(i) for i in xrange(1,12)]
def main():
for acc in (acc0, acc1, acc2):
test(acc)
print
if __name__ == '__main__':
main()
正如拉斯曼所说,你真的不应该这样做。使用副作用的疯狂列表理解比行为良好的自足理解更难阅读和理解
但是如果你仍然好奇的话,这里有一个不同的方法。它使用可变的默认功能参数来保存状态
def adder(x, last=[]):
if last == []:
last.append(0)
last[0] += x
return last[0]
b = (1, 2, 3, 4)
print [adder(x) for x in b]
显然,这比for循环更冗长、更难阅读,而且我敢说它的效率也要低得多。而且它依赖于Python的一个特性(可变默认函数参数的行为),这对于新的Python程序员来说并不容易理解(而且许多有经验的Python程序员也不是特别满意)
所以请不要在你的代码中使用这种疯狂
编辑 这里有一些更多的方法可以通过列表理解来做这种坏事 首先,在序列的切片副本上使用
sum
的方法效率极低:
b = (10, 20, 30, 40)
[sum(b[:1+i]) for i in xrange(len(b))]
类似的丑陋,这次使用reduce
。Guido讨厌在最好的时候减少,所以我不想想象他会怎么看待这个怪物
这里还有一些是我不久前设计的,两个使用函数属性保存状态,最后一个使用类保存状态,这可能是最不讨厌的方式
#! /usr/bin/env python
''' Create an accumulator function from a 2 arg function.
Like a cross between map() & reduce().
'''
def acc0(func, v0=0):
def f(v):
f.v = func(f.v, v)
return f.v
f.v = v0
return f
def acc1(func, v0=0):
def f(v, c=None):
if c!=None:
f.v = c
f.v = func(f.v, v)
return f.v
f.v = v0
return f
class acc2(object):
def __init__(self, func, value=0):
self.v = value
self.func = func
def __call__(self, x):
self.v = self.func(self.v, x)
return self.v
def test(acc):
g = acc(lambda u,v: u+v)
print [g(i) for i in xrange(1,12)]
f = acc(lambda u,v: u*v, 1)
print [f(i) for i in xrange(1,12)]
f.v = 10
print [f(i) for i in xrange(1,12)]
f.v = 1
print [f(i) for i in xrange(1,15)]
f.v = 2
print [f(i) for i in xrange(1,12)]
g.v = 0
print [g(i) for i in xrange(1,12)]
g.v = 100
print [g(i) for i in xrange(1,12)]
def main():
for acc in (acc0, acc1, acc2):
test(acc)
print
if __name__ == '__main__':
main()
既然我们已经把你吓得够呛了,那么我将向你展示更多做这类事情的方法。:)既然我们已经把你吓得够呛了,那么我将向你展示更多做这类事情的方法。:)