Python 用不同的语句列出理解示例

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 有很多方法可以把它写成一个理解列表,但是你真的不应该。理解用于

如果我有下一个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

有很多方法可以把它写成一个理解列表,但是你真的不应该。理解用于面向表达式的编程,循环用于副作用。

有一些方法可以将其作为列表理解来编写,但您确实不应该这样做。理解用于面向表达式的编程,循环用于副作用。

在列表理解中不能使用打印。您应该保留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()

既然我们已经把你吓得够呛了,那么我将向你展示更多做这类事情的方法。:)既然我们已经把你吓得够呛了,那么我将向你展示更多做这类事情的方法。:)