迭代文件中的行会产生错误的行数

时间:2016-05-06 02:04:41

标签: python

我正逐渐熟悉Python,但在我认为简单的脚本中遇到了一个主要障碍。

可编程红外遥控器以称为ProntoEdit HEX的文件格式存储其红外代码。这本质上是一个长文件,文件中的每一行代表特定IR代码的数据。数据以十六进制数表示,每个数据之间有一个空格。我编辑了文件,因此每行只包含十六进制数字,每个数字之间有一个空格(在十六进制数字之前没有0x)。每行有64个十六进制数。它们是成对的,因此每行包含32对。为了将数据转换为简单的二进制字符串,您将每对的第二个数除以第一个,并根据比率,它是1或0.

希望你已经完成了所有这些。我已经设法用Python编写一个脚本来为我自动执行此操作,因为我开始使用的文件中有768行。该脚本似乎正在工作,但由于某种原因,它只执行文件的一半,然后停止。它似乎也在跳过文件的第一行。我已经手动检查了,它是正确的"解码"从第二行直到文件的中途,在第384行。我不知道为什么会发生这种情况。

这是(相对)简单的脚本:

rawcode = open(r"stripped.txt", "r")
outputfile = open(r"output_codes.txt", "w")
currentline = 0
for lines in rawcode:
    output = [] #empty list for output
    line = rawcode.readline()
    splitline = line.split(" ") #turn the line into a list
    splitline.remove('\n')

    y = 0
    for x in list(range(32)): #go through each pair in the line
        num1 = int(splitline[y], 16)
        num2 = int(splitline[y+1], 16)
        if (num2 / num1) == 3:
            output.append("0")
        elif (num2 / num1) == 7:
            output.append("1")
        y += 2

    print(output)
    outstring = ''.join(output)
    outputfile.write(outstring)
    outputfile.write("\n")
    currentline += 1
    print(currentline)

outputfile.flush()
outputfile.close()
rawcode.close()

此外,这里是输入文件的链接,以及我得到的输出文件。

stripped.txt

output.txt

如果有人有以这种方式处理文件的经验,非常感谢您的帮助!我真的不熟悉Python的复杂性 - 正如你可能会说的那样,我来自C背景,并且仍然在努力解决两种语言的不同哲学问题。

2 个答案:

答案 0 :(得分:5)

你在这里做双读:

for lines in rawcode:
    output = [] #empty list for output
    line = rawcode.readline()

目前还不清楚你要完成什么,因为你对这个过程的描述毫无意义。 (这可能是准确的,但它仍然没有意义:除以然后舍入到1或0?)

好的,这似乎有效:

#!python3

with open('stripped.txt') as infile, open('output.txt', 'w') as outfile:
    for line in infile:
        line = line.strip()
        if not line:
            continue

        hexnums = [int(hn, 16) for hn in line.split()]
        for num1, num2 in zip(hexnums[0::2], hexnums[1::2]):
            digit = '0' if num2 // num1 == 3 else '1'
            outfile.write(digit)
        outfile.write('\n')

我得到768行输出,就像输入一样,第一组是:

01000000000000010100011111111111
01000100000000010100001111111111
01000010000000010100010111111111
01000110000000010100000111111111
01000001000000010100011011111111
01000101000000010100001011111111
01000011000000010100010011111111
01000111000000010100000011111111
01000000100000010100011101111111
01000100100000010100001101111111
01000010100000010100010101111111
01000110100000010100000101111111
01000001100000010100011001111111
01000101100000010100001001111111
01000011100000010100010001111111
01000111100000010100000001111111
01000000010000010100011110111111
01000100010000010100001110111111
01000010010000010100010110111111
01000110010000010100000110111111

答案 1 :(得分:2)

您不需要调用readline()。你基本上每隔一行阅读一次。使用迭代器中的行var,你应该得到每一行。

当你调用readline()时,你会拉下一行并忽略你已从行中获得的那行