访问第n行csv文件的最佳方法

Gab*_*eux 28 python csv file python-3.x

我必须访问CSV文件中的第N行.

这是我做的:

import csv

the_file = open('path', 'r')
reader = csv.reader(the_file)

N = input('What line do you need? > ')
i = 0

for row in reader:
    if i == N:
        print("This is the line.")
        print(row)
        break

    i += 1

the_file.close()
Run Code Online (Sandbox Code Playgroud)

......但这并不是最佳的.编辑精度:如果文件很大,我不想遍历所有行,我不想将整个文件加载到内存中.

我确实希望reader[N]存在类似的东西,但我还没有找到它.

编辑答案:这一行(来自选择的答案)是我正在寻找的:

next(itertools.islice(csv.reader(f), N, None)
Run Code Online (Sandbox Code Playgroud)

Stu*_*art 35

它没什么区别,但它使用起来enumerate比使用自己的计数器变量要轻一些.

for i, row in enumerate(reader):
    if i == N:
        print("This is the line.")
        print(row)
        break
Run Code Online (Sandbox Code Playgroud)

您还可以使用itertools.islice针对此类场景设计的场景 - 访问迭代的特定切片而无需将整个内容读入内存.它应该比循环不需要的行更有效.

with open(path, 'r') as f:
    N = int(input('What line do you need? > '))
    print("This is the line.")
    print(next(itertools.islice(csv.reader(f), N, None)))
Run Code Online (Sandbox Code Playgroud)

但是如果您的CSV文件很小,只需将整个内容读入一个列表,然后您可以通过正常方式使用索引进行访问.这样做的另一个好处是,您可以按随机顺序访问多个不同的行,而无需重置csv阅读器.

my_csv_data = list(reader)
print(my_csv_data[N])
Run Code Online (Sandbox Code Playgroud)

  • pythons csv reader 有一个 line_num 属性,因此如果您不想,则不必使用 enumerate 。类似... if reader.line_num == N: 做某事 (2认同)

iCo*_*dez 7

你的解决方案实际上没那么糟糕.将文件迭代器推进到您想要的行是一种很好的方法,并且在许多情况下都会使用.

如果你想要它更简洁,你可以使用nextenumerate使用生成器表达式:

import csv

the_file = open('path', 'r')
reader = csv.reader(the_file)

N = int(input('What line do you need? > '))

line = next((x for i, x in enumerate(reader) if i == N), None)
print(line)

the_file.close()
Run Code Online (Sandbox Code Playgroud)

None在那里是,如果线路没有发现什么将返回(N太大).您可以选择任何其他值.


您还可以使用with语句打开文件以使其自动关闭:

import csv

with open('path', 'r') as the_file:
    reader = csv.reader(the_file)

    N = int(input('What line do you need? > '))

    line = next((x for i, x in enumerate(reader) if i == N), None)
    print(line)
Run Code Online (Sandbox Code Playgroud)

如果你真的想减小尺寸,你可以这样做:

from csv import reader
N = int(input('What line do you need? > '))
with open('path') as f:
    print(next((x for i, x in enumerate(reader(f)) if i == N), None))
Run Code Online (Sandbox Code Playgroud)


mar*_*eau 7

itertools模块具有许多用于创建专用迭代器的函数 - 其islice()功能可用于轻松解决此问题:

import csv
import itertools

N = 5  # desired line number

with open('path.csv', newline='') as the_file:
    row = next(csv.reader(itertools.islice(the_file, N, N+1)))

print("This is the line.")
print(row)
Run Code Online (Sandbox Code Playgroud)

PS对于好奇,我最初的反应 - 也有效(可以说更好) - 是:

    row = next(itertools.islice(csv.reader(the_file), N, N+1))
Run Code Online (Sandbox Code Playgroud)

  • @JonClements对于因子2的"N = 16 ... 4096",我的方法的速度优势是"[2,3,5,7,10,12,12,15,16]"的因素. (2认同)

ajm*_*tin 6

你可以简单地做:

n = 2 # line to print
fd = open('foo.csv', 'r')
lines = fd.readlines()
print lines[n-1] # prints 2nd line
fd.close()
Run Code Online (Sandbox Code Playgroud)

或者通过不将整个文件加载到内存中来更好地利用更少的内存:

import linecache
n = 2
linecache.getline('foo.csv', n)
Run Code Online (Sandbox Code Playgroud)

  • CSV中的多行字段怎么样? (2认同)
  • 据我所知,CSV格式允许在字段中换行,只要它们在双引号内(第2节,第6段),所以如果有任何可能性,最好使用`csv.reader` (2认同)