当前位置:  开发笔记 > 编程语言 > 正文

Python中意外的列表理解行为

如何解决《Python中意外的列表理解行为》经验,为你挑选了1个好方法。

我相信我会被嵌套的范围规则和列表推导的某些组合所困扰. Jeremy Hylton的博客文章暗示了原因,但我并不完全理解CPython的实现,足以弄清楚如何解决这个问题.

这是一个(过于复杂的?)示例.如果人们有一个更简单的演示,我想听听它.问题:使用next()的列表推导用最后一次迭代的结果填充.

编辑:问题:

到底是怎么回事,我该如何解决这个问题?我是否必须使用标准循环?显然,该函数运行的次数正确,但列表推导最终得到的是最终值而不是每个循环的结果.

一些假设:

发电机?

懒惰填写列表理解?

import itertools
def digit(n):
    digit_list = [ (x,False) for x in xrange(1,n+1)]
    digit_list[0] = (1,True)
    return itertools.cycle ( digit_list)
>>> D = digit(5)
>>> [D.next() for x in range(5)]
## This list comprehension works as expected
[(1, True), (2, False), (3, False), (4, False), (5, False)]
class counter(object):
    def __init__(self):
        self.counter = [ digit(4) for ii in range(2) ] 
        self.totalcount=0
        self.display = [0,] * 2
    def next(self):
        self.totalcount += 1
        self.display[-1] = self.counter[-1].next()[0]
        print self.totalcount, self.display
        return self.display

    def next2(self,*args):
        self._cycle(1)
        self.totalcount += 1
        print self.totalcount, self.display
        return self.display

    def _cycle(self,digit):
        d,first = self.counter[digit].next()
        #print digit, d, first
        #print self._display
        self.display[digit] = d
        if first and digit > 0:
            self._cycle(digit-1)


C = counter()
[C.next() for x in range(5)]
[C.next2() for x in range(5)]

OUTPUT

In [44]: [C.next() for x in range(6)]
1 [0, 1]
2 [0, 2]
3 [0, 3]
4 [0, 4]
5 [0, 1]
6 [0, 2]
Out[44]: [[0, 2], [0, 2], [0, 2], [0, 2], [0, 2], [0, 2]]

In [45]: [C.next2() for x in range(6)]
7 [0, 3]
8 [0, 4]
9 [1, 1]
10 [1, 2]
11 [1, 3]
12 [1, 4]
Out[45]: [[1, 4], [1, 4], [1, 4], [1, 4], [1, 4], [1, 4]]

# this should be:  [[0,3],[0,4]....[1,4]] or similar

mweerden.. 15

问题是,return self.display您返回对此列表的引用(而不是副本).所以你最终得到的是一个列表,其中每个元素都是self.display的引用.为了说明,请看以下内容:

>>> a = [1,2]
>>> b = [a,a]
>>> b
[[1, 2], [1, 2]]
>>> a.append(3)
>>> b
[[1, 2, 3], [1, 2, 3]]

你可能想要使用类似的东西return self.display[:].



1> mweerden..:

问题是,return self.display您返回对此列表的引用(而不是副本).所以你最终得到的是一个列表,其中每个元素都是self.display的引用.为了说明,请看以下内容:

>>> a = [1,2]
>>> b = [a,a]
>>> b
[[1, 2], [1, 2]]
>>> a.append(3)
>>> b
[[1, 2, 3], [1, 2, 3]]

你可能想要使用类似的东西return self.display[:].

推荐阅读
郑谊099_448
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有