0

假设有一个文件包含多行数字和注释,例如:

#comments
12 #this is number
2.4 #this is float

读取文件并将数字附加到列表中。我试图只获取数字,但它以某种方式附加了#this is number 和#this is float。

4

3 回答 3

4

你可以使用split

>>> 'foo #comment'.split('#', 1)[0]
'foo '
>>> 'foo comment'.split('#', 1)[0]
'foo comment'
于 2013-04-29T02:16:50.033 回答
2

对于这样一个简单的案例,您不必使用更复杂、更慢的正则表达式re模块)机制。str.split()是你的朋友

output = []

with open('somefile.txt') as f:
    for line in f:
        parts = line.split('#', 1)  # Maximum 1 split, on comments
        try:
            output.append(float(parts[0]))  # The single, or pre-comment part is added
        except ValueError:  # Beginning is not float-like: happens for "# comment", "    # comment", etc.
            pass  # No number found

这会自动处理所有可能的浮点语法1.1e2nan-inf3等)。它之所以有效是因为float()它非常强大:它处理尾随空格和换行符(通过忽略它们)。

这也非常有效,因为try不失败的 a 很快(通常比显式测试快)。

这也处理文件中间的注释。 如果你在文件的开头只有一个纯注释,我们可以简化代码并使用保证每一行都有一个数字的事实:

output = []

with open('somefile.txt') as f:
    next(f)  # Skips the first, comment line
    for line in f:
        output.append(float(line.split('#', 1)[0]))  # The single or pre-comment part is guaranteed to be a float representation

我不认为有任何比这更简单的显式方法(除了计算可能太多的行部分split('#'))。

也就是说,可以考虑使用隐式方法eval(line),例如 abathur 的方法,其中替换整个float(…)部分;但是,在这种情况下,代码并没有显示预期的浮点数,并且正如Python 之禅所说,“显式优于隐式。”,所以我不建议使用这种eval()方法,除非它是为了一个-拍摄,快速和肮脏的脚本。

于 2013-04-29T03:15:26.653 回答
0

虽然其他人已经介绍了文件读取物流,但我只想指出另一种方法:假设您拥有的文件遵循 Python 的语法,您可以使用eval函数获取该行的值减去注释。

>>> eval("10 #comment")
10

当然请记住,在eval()执行 Python 代码时存在安全考虑,如果您对数据文件的控制比对正在执行它的脚本的控制更少,那么任意代码执行可能是您的程序的一个漏洞。

于 2013-04-29T02:31:53.070 回答