5

我有一个大约 25000 行的文件,它是一个 s19 格式的文件。

每行就像:S214 780010 00802000000010000000000A508CC78C 7A

实际文件中没有空格,第一部分780010是这一行的地址,我希望它是一个dict的键值,我希望数据部分00802000000010000000000A508CC78C是这个键的值。我这样写我的代码:

def __init__(self,filename):
    infile = file(filename,'r')
    self.all_lines = infile.readlines()
    self.dict_by_address = {}

    for i in range(0, self.get_line_number()):
        self.dict_by_address[self.get_address_of_line(i)] = self.get_data_of_line(i)

    infile.close()

get_address_of_line() 和 get_data_of_line() 都是简单的字符串切片函数。get_line_number() 遍历 self.all_lines 并返回一个 int

问题是,初始化过程需要我超过 1 分钟,是我构造 dict 的方式错误还是 python 只需要这么长时间才能做到这一点?

顺便说一句,我是 python 新手 :) 也许代码看起来更像 C/C++,任何关于如何像 python 一样编程的建议都值得赞赏:)

4

2 回答 2

9

这样的事情怎么样?(我只用一行做了一个测试文件,S21478001000802000000010000000000A508CC78C7A所以你可能需要调整切片。)

>>> with open('test.test') as f:
...     dict_by_address = {line[4:10]:line[10:-3] for line in f}
... 
>>> dict_by_address
{'780010': '00802000000010000000000A508CC78C'}
于 2012-04-16T03:29:57.307 回答
5

这段代码应该比你现在拥有的要快得多。编辑:正如@sth 指出的那样,这不起作用,因为实际文件中没有空格。我会在最后添加一个更正的版本。

def __init__(self,filename):
    self.dict_by_address = {}

    with open(filename, 'r') as infile:
        for line in infile:
            _, key, value, _ = line.split()
            self.dict_by_address[key] = value

一些评论:

  • Python 中的最佳实践是使用with语句,除非您使用的是没有它的旧 Python。

  • 最佳做法是使用open()而不是file(); 我认为 Python 3.x 甚至没有file().

  • 您可以将打开的文件对象用作迭代器,当您对其进行迭代时,您会从输入中得到一行。这比调用.readlines()方法要好,后者将所有数据放入一个列表中;然后您使用数据一次并删除列表。由于输入文件很大,这意味着您可能会导致交换到虚拟内存,这总是很慢。此版本避免构建和删除巨型列表。

  • 然后,在创建了一个巨大的输入行列表之后,您range()可以创建一个很大的整数列表。再次浪费时间和内存来构建一个列表,使用它一次,然后删除该列表。您可以通过使用来避免这种开销,xrange()但更好的方法是随时构建字典,作为从文件中读取行的同一循环的一部分。

  • 使用您的特殊切片函数提取“地址”和“数据”字段可能会更好,但如果输入是常规的(始终遵循您示例的模式),您可以按照我在此处显示的内容进行操作。 line.split()在空白处分割行,给出四个字符串的列表。然后我们使用“解构赋值”将它解压成四个变量。由于我们只想保存其中两个值,因此我_为其他两个使用了变量名(一个下划线)。这不是一个真正的语言特性,但它是 Python 社区的一个习惯用法:当你有你不关心的数据时,你可以将它分配给_. 如果有任何数量的值不是 4,此行将引发异常,因此如果可能有空行或注释行或其他任何内容,您应该添加检查并处理错误(至少将该行包装在try:/ except)。

编辑:更正版本:

def __init__(self,filename):
    self.dict_by_address = {}

    with open(filename, 'r') as infile:
        for line in infile:
            key = extract_address(line) 
            value = extract_data(line)
            self.dict_by_address[key] = value
于 2012-04-16T03:28:53.390 回答