2014-10-17 94 views
0

所以我正在阅读这个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 > 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”不应该在那里。

+0

“当我写的小例子,行为怪异消失”是写在首位最小的例子的原因主要部分。这给你一个完美的方式来进行:加回你跳过的东西的一半。问题是否回来了?然后将其中一半退出。如果没有,将其余一半的东西放回去。等等。在大约2-3次迭代中,您通常可以确切地确定事情出错的地方。 – abarnert 2014-10-17 00:29:13

+0

同时,请提供一些样本输入,以及所需的和实际的输出。 – abarnert 2014-10-17 00:30:44

+0

作为一个附注,你显然知道'with'语句,因为你使用'infile'。那么为什么你不使用'outfile'呢? (另外,你为什么重复使用'outfile'这个名字来表示文件名和打开的文件对象?这种事情在调试的时候会导致混乱。) – abarnert 2014-10-17 00:31:57

回答

3

问题是,您在声明
[None for i in range(width*3)]中更改了i的值。当它遇到if i > 2时,i将是width*3 - 1,其然后评估为True
只需更改变量名称([None for j in range(width*3)])即可。请注意0​​表示要打印的第一行将是第四行(索引3)。如果你想要第三个打印,你应该使用if i > 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() 
+0

或者'[None] *(width * 3) '! – Ryan 2014-10-17 00:38:21

+1

在这里使用'elif'而不是'if'也可以解决问题,并且OP确实应该做出更改(或全部三项)。 – abarnert 2014-10-17 00:39:22

+0

不知何故,我不喜欢@minitech提到的那种符号,仅仅是因为在执行诸如'a = [[1,2]] * 3',然后是'a [0] [0] = 2'时会遇到问题'改变每一个项目。当然,这里不适用,但我对这种符号产生了非理性的恐惧;) – greschd 2014-10-17 00:46:41