11

如何在 Python 3 中获取字符串的第 n行?例如

getline("line1\nline2\nline3",3)

有没有办法使用 stdlib/builtin 函数来做到这一点?我更喜欢 Python 3 中的解决方案,但 Python 2 也很好。

4

9 回答 9

25

尝试以下操作:

s = "line1\nline2\nline3"
print s.splitlines()[2]
于 2012-07-15T12:24:45.803 回答
5

功能性方法

>>> import StringIO
>>> from itertools import islice
>>> s = "line1\nline2\nline3"
>>> gen = StringIO.StringIO(s)
>>> print next(islice(gen, 2, 3))
line3
于 2012-07-15T13:07:06.320 回答
4
`my_string.strip().split("\n")[-1]`
于 2018-10-24T01:03:12.920 回答
3

使用字符串缓冲区:

import io    
def getLine(data, line_no):
    buffer = io.StringIO(data)
    for i in range(line_no - 1):
        try:
            next(buffer)
        except StopIteration:
            return '' #Reached EOF

    try:
        return next(buffer)
    except StopIteration:
        return '' #Reached EOF
于 2012-07-15T12:31:09.997 回答
3

比拆分字符串更有效的解决方案是遍历其字符,找到第 N 次和第 (N - 1) 次出现 '\n' 的位置(考虑到字符串开头的边缘情况) . 第 N 行是这些位置之间的子字符串。

这是一段杂乱的代码来演示它(行号为 1 索引):

def getLine(data, line_no):
    n = 0
    lastPos = -1
    for i in range(0, len(data) - 1):
        if data[i] == "\n":
            n = n + 1
            if n == line_no:
                return data[lastPos + 1:i]
            else:
                lastPos = i;



    if(n == line_no - 1):
        return data[lastPos + 1:]
    return "" # end of string

这也比一次构建一个字符的字符串的解决方案更有效。

于 2012-07-15T12:32:20.920 回答
2

从评论看来,这个字符串似乎非常大。如果有太多数据无法舒适地放入内存中,一种方法是逐行处理文件中的数据:

N = ...
with open('data.txt') as inf:
    for count, line in enumerate(inf, 1):
        if count == N: #search for the N'th line
            print line

使用enumerate()为您提供了您正在迭代的对象的索引和值,您可以指定一个起始值,所以我使用 1(而不是默认值 0)

使用的好处with是它会在您完成或遇到异常时自动为您关闭文件。

于 2012-07-15T12:22:23.717 回答
1

既然您提出了内存效率的问题,这是否更好:

s = "line1\nline2\nline3"

# number of the line you want
line_number = 2

i = 0
line = ''
for c in s:
   if i > line_number:
     break
   else:
     if i == line_number-1 and c != '\n':
       line += c
     elif c == '\n':
       i += 1
于 2012-07-15T12:45:54.853 回答
0

为了可读性写成两个函数

    string = "foo\nbar\nbaz\nfubar\nsnafu\n"

    def iterlines(string):
      word = ""
      for letter in string:
        if letter == '\n':
          yield word
          word = ""
          continue
        word += letter

    def getline(string, line_number):
      for index, word in enumerate(iterlines(string),1):
        if index == line_number:
          #print(word)
          return word

    print(getline(string, 4))
于 2018-09-20T16:15:10.567 回答
-3

我的解决方案(高效且紧凑):

def getLine(data, line_no):
    index = -1
    for _ in range(line_no):index = data.index('\n',index+1)
    return data[index+1:data.index('\n',index+1)]
于 2012-07-15T13:05:23.010 回答