【问题标题】:Strange behavior from enumerate()来自 enumerate() 的奇怪行为
【发布时间】:2014-10-17 00:17:08
【问题描述】:

所以我正在读取这个 PPM 文件,逐行读取它,在这里和那里对其进行操作,然后将新行写入另一个文件。我尝试制作一个最小的工作示例来重现该行为,但是当我编写一个最小的示例时,奇怪的行为就消失了——但我无法弄清楚这是什么部分导致了奇怪的行为。所以完整的代码如下。

def flip_horizontal(infile, outfile):
with open(os.getcwd() + '\\' + infile, 'r') as f:
    outfile = open(os.getcwd() + '\\' + outfile, 'w')
    rgbCounter = 0
    for i, line in enumerate(f):
        if i < 3:
            outfile.write(line)
        if i == 1:
            width = int(line.split()[1])
            lineList = [None for i in range(width*3)]
            if width > 1024:
                print "Image size too large:  Buffer can only store 1024 \
                    pixels at a time.  Aborting negate_red."
                break
        if i > 2:
            print line
            for integer in line.split():
                if rgbCounter%3 == 0:
                    lineList[width*3-rgbCounter-3] = integer
                elif rgbCounter%3 == 1:
                    lineList[width*3-rgbCounter-1] = integer
                else:
                    lineList[width*3-rgbCounter+1] = integer
                rgbCounter += 1
                if rgbCounter == width*3:
                    outfile.write(' '.join(lineList))
                    outfile.write('\n')
                    rgbCounter = 0
    outfile.close()

问题出在:当我运行这段代码时,if i &gt; 2: 之后的“打印”行也会打印第 2 行(或者更确切地说,第 3 行,即索引为 2 的行)!在一个更简单的例子中,如果我只是说

...
if i > 2:
    print line
...

它只会打印第 4 行及之后的代码,但我实际运行的其余代码会打印第 3 行。任何想法为什么以及如何解决这个问题?

这是一个示例输入:

P3
4 4
255
49   49   49    100   100   100     0   200   0     0   0   0 
100  100  100   100   0     0       200 200   200   255 255 255
200  100  0     0     100   200     0   0     0     50  50  50
0    0    0     0     0     0       0   0     0     0   0   0

当我运行代码时,我得到了打印的行

4 4

49   49   49    100   100   100     0   200   0     0   0   0 

100  100  100   100   0     0       200 200   200   255 255 255

...

包含“4 4”的第一行不应该在那里。

【问题讨论】:

  • “当我编写最小示例时,奇怪的行为就会消失”是首先编写最小示例的主要原因。这为您提供了一种完美的继续方式:将您跳过的一半内容添加回来。问题又回来了吗?然后取出一半。如果没有,把剩下的一半放回去。等等。在大约 2-3 次迭代中,您通常可以准确地确定哪里出了问题。
  • 同时,请提供一些示例输入,以及期望的和实际的输出。
  • 附带说明一下,您显然知道with 语句,因为您使用的是infile 语句。那么你为什么不也使用一个outfile 呢? (另外,你为什么要重复使用名称outfile 来表示文件名和打开的文件对象?这种事情肯定会在调试时导致混乱。)

标签: python python-2.7 enumerate


【解决方案1】:

问题是您正在更改语句
[None for i in range(width*3)]i 的值。 i 在遇到 if i &gt; 2 时将是 width*3 - 1,然后计算结果为 True
只需更改变量的名称 ([None for j in range(width*3)]) 即可。请注意,i &gt; 2 表示要打印的第一行将是第四行(索引 3)。如果你想打印第三个,你应该使用if i &gt; 1
显示行为的最小示例:

def test():
    a = ['a', 'b', 'c', 'd']
    for i, char in enumerate(a):
        if i==1:
            var = [None for i in range(4)]
        if i>2:
            print(i, char)
             test()

【讨论】:

  • 或者,[None] * (width * 3)!
  • 在此处使用elif 而不是if 也可以解决问题,并且OP 确实应该进行两个 更改(或全部三个)。
  • 不知何故我不喜欢@minitech 提到的那个符号,只是因为你在做a = [[1,2]]*3 之类的事情时会遇到问题,然后a[0][0] = 2 会更改每个项目。当然,不适用于这里,但我对这种表示法产生了一种非理性的恐惧;)
猜你喜欢
  • 2020-02-10
  • 2014-01-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多