在 python 中保持格式的同时将字符串列表转换为整数
Posted
技术标签:
【中文标题】在 python 中保持格式的同时将字符串列表转换为整数【英文标题】:List of strings to integers while keeping a format in python 【发布时间】:2012-08-01 18:51:10 【问题描述】:所以我想做的事情似乎比较简单,但对于我的生活,我就是无法完全做到。我有一个 .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']
我做了什么
好吧,它是我在 *** 上的 found 的 different 的混搭,但我认为我会以最繁琐的方式进行处理。而this 在我实现它时没有任何意义.. 尽管它可能与空格问题处于同一轨道..
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 并且是初学者。
【问题讨论】:
【参考方案1】: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]
【讨论】:
完美,这正是我想要的!感谢您的编辑。它更符合我的需要。 @Ason -- 没问题。我更仔细地重新阅读了您的帖子,并发现您不需要在新文件中使用它,除非这是完成此操作的最简单方法。所以,我更新了。 @Ason -- 我也将它压缩为 1-liner(并添加了它作为替代方案)。我不喜欢多行版本,但它不是太糟糕所以可能有些人更喜欢它。 @mgilson 作为一个初学者,我喜欢看到更多我正在做的事情,所以我会坚持使用多线,但感谢您为未来的用户添加更多信息!跨度> @mgilson 只是为了澄清一下,是否有必要将字符串转换为整数来减去1
?我读到字符串是不可更改的。【参考方案2】:
这是使用正则表达式完成此任务的一种非常直接的方法。这样做的好处是格式可以保证保持完全相同,因为它将替换原处的数字而不会触及任何空白:
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')
【讨论】:
非常感谢您的回答!我对正则表达式不是很熟悉,所以我必须选择一个不同的答案,因为它更容易理解和实施。但是 +1 可以帮助未来的访问者! 好主意,虽然我认为您的意思是match.group
而不是 m.group
。同样,您可能想让sub_one_repl
更安全一点(即,如果正则表达式无法匹配 .group 将导致异常),或者只是做一个 lambda。您也可以将其作为列表组合或生成器表达式:(re.sub(r'\d+', lambda m: str(int(m.group(0))-1), line) for line in original.readlines())
@AdamParkin - 谢谢,我最初有 m
作为参数,忘记更新函数。 sub_one_repl
只会在成功匹配时被调用,它总是全为数字,所以它应该是安全的。单行是一种选择,但我仍然会将lambda
移到它之外,这样您就不会在每次迭代时重新创建函数。【参考方案3】:
另一种方法是使用 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]]
【讨论】:
【参考方案4】:试试这个:
with open(filepath) as f:
for line in f:
print " ".join([str(int(i)-1) for i in line.split()])
希望有帮助
【讨论】:
以上是关于在 python 中保持格式的同时将字符串列表转换为整数的主要内容,如果未能解决你的问题,请参考以下文章
在 Java 中,如何将字节数组转换为十六进制数字字符串,同时保持前导零? [复制]
在 Java 中,如何将字节数组转换为十六进制数字字符串,同时保持前导零? [复制]