5

所以我想做的事情似乎比较简单,但对于我的生活,我就是不能完全得到它。我有一个 .txt 文件,例如

4 2
6 5 1
9 4 5

我希望它的信息可以像这样提供给我(即,除非有必要,否则我不需要编写新的 .txt 文件。)...

3 1
5 4 0
8 3 4

或者,1从每个数字中减去,但格式保持不变。永远不会有比1原始数字更大的数字,因此不可能出现负数。这整个头痛是由于将索引转换为以开头0而不是1. 可能使事情复杂化的是原始文件的打印方式如下

['4 2 /n','6 5 1 /n', '9 4 5 /n']

我做了什么

好吧,它是我在 StackOverflow 上发现的各种不同东西的混搭,但我认为我会以最繁琐的方式来处理它。当我实现它时,这个没有意义..虽然它可能与空格问题在同一轨道上..

origianl = open(file, 'r')
for line in original.readlines():
    newline = line.replace(" \n","")
    finalWithStrings.append(newline)

finalWithIntegers = [map(int,x) for x in finalWithStrings]
finalWithIntegers[:] = [x-1 for x in finalWithIntegers]

我的想法是,我需要删除“/n”并将这些字符串转换为整数,以便可以从中减去1。并以某种方式保持格式。格式必须相同,因为每一行都包含另一个文件的类似索引行的信息,这一点很重要。我不想在最终结果(或打印语句)中看到“/n”,但我仍然想要换行开始的效果。然而,上面的代码不起作用有两个原因(我知道)。

int(n[:])抛出一个错误,因为它不喜欢空格,当我在其中输入一个值(比如 0)时,代码会在每一行上打印第一个数字并减去一个......并将其全部放在一行上。

[3, 5, 8]

因此,取出一个回车并必须再输入一个似乎是多余的,但我确实需要保持格式,并且有办法获取所有数字!

这也不起作用:

for line in original.readlines():
    newline = line.replace(" \n","")
    finalWithStrings.append(newline)

finalWithIntegers = [map(int,x) for x in finalWithStrings]
finalWithIntegers[:] = [x-1 for x in finalWithIntegers]    

但不仅仅是一个错误的输出,而是一个错误:

ValueError:invalid literal for int() with base 10:''

有没有人对我在这里做错了什么以及如何解决这个问题有任何想法?我正在使用 Python 2.6 并且是初学者。

4

4 回答 4

9
with open("original_filename") as original:
    for line in original:
        #if you just want the line as integers:
        integers = [ int(i) - 1 for i in line.split() ]
        #do something with integers here ...

        #if you want to write a new file, use the code below:
        #new_line = " ".join([ str(int(i) - 1) for i in line.split() ])
        #newfile.write(new_line + '\n')

在上面的示例中,我在上下文管理器中打开了您的文件,因为这是一种很好的做法(从 2.5 版开始)。上下文管理器确保您的文件在您退出该上下文时正确关闭。

编辑

看起来您可能正在尝试创建一个 2D 列表...为此,可以使用以下方法:

data = []
with open("original_filename") as original:
    for line in original:
        integers = [ int(i) - 1 for i in line.split() ]
        data.append(integers)

或者,如果您更喜欢 1-liner(我不喜欢):

with open("original_filename") as original:
    data = [ [int(i) for i in line.split()] for line in original ]

现在如果你打印它:

for lst in data:
    print (lst)    # [3, 1]
                   # [5, 4, 0]
                   # [8, 3, 4]
于 2012-08-03T17:32:46.550 回答
4

这是使用正则表达式完成此任务的一种非常直接的方法。这里的好处是格式可以保证保持完全相同,因为它将替换原处的数字而不会触及任何空白:

import re

def sub_one_repl(match):
    return str(int(match.group(0))-1)

for line in original.readlines():
    newline = re.sub(r'\d+', sub_one_repl, line).rstrip('\n')
于 2012-08-03T17:39:11.323 回答
2

另一种方法是使用 csv 模块和列表理解:

from csv import reader

data = [[int(j) - 1 for j in i] for i in reader(open("your_file"), delimiter=' ')]

例如,它会使用您的数据:

[[3, 1], [5, 4, 0], [8, 3, 4]]
于 2012-08-03T18:00:43.333 回答
0

试试这个:

with open(filepath) as f:
    for line in f:
        print " ".join([str(int(i)-1) for i in line.split()])

希望有帮助

于 2012-08-03T17:43:39.027 回答