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

时间:2014-12-05 01:35:49

标签: python file csv 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()

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

我确实希望存在类似reader[N]的内容,但我还没有找到它。

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

next(itertools.islice(csv.reader(f), N, None)

6 个答案:

答案 0 :(得分:32)

它没有什么区别,但使用enumerate而不是制作自己的计数器变量稍微清晰。

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

您还可以使用专为此类场景设计的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)))

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

my_csv_data = list(reader)
print(my_csv_data[N])

答案 1 :(得分:7)

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

如果您希望它更简洁,可以next使用enumerategenerator expression

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()

如果找不到该行(None太大),那么N会返回什么。您可以选择任何其他值。


您也可以使用with-statement打开文件,让它自动关闭:

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)

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

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))

答案 2 :(得分:6)

您可以这样做:

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

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

import linecache
n = 2
linecache.getline('foo.csv', n)

答案 3 :(得分:6)

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)

P.S。对于好奇的人,我最初的反应 - 也有效(可以说更好) - 是:

    row = next(itertools.islice(csv.reader(the_file), N, N+1))

答案 4 :(得分:3)

您可以将for循环最小化为理解表达式,例如

row = [row for i,row in enumerate(reader) if i == N][0]  

# or even nicer as seen in iCodez code with next and generator expression

row = next(row for i,row in enumerate(reader) if i == N)

答案 5 :(得分:3)

import csv
with open('cvs_file.csv', 'r') as inFile: 
    reader = csv.reader(inFile)
    my_content = list(reader)

line_no = input('What line do you need(line number begins from 0)? > ')
if line_no < len(my_content):
    print(my_content[line_no])
else:
    print('This line does not exists')

作为result现在,您可以通过其index directly获取任何行:

What line do you need? > 2
['101', '0.19', '1']

What line do you need? > 100
This line does not exists