Подтвердить что ты не робот

Лучший способ доступа к N-й строке файла csv

Мне нужно получить доступ к N-й строке в файле CSV.

Вот что я сделал:

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

Ответ 1

Это не имеет большого значения, но немного чище использовать 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 файл невелик, просто прочитайте всю вещь в списке, который вы можете получить с индексом обычным способом. Это также имеет то преимущество, что вы можете получить доступ к нескольким различным строкам в случайном порядке, не имея reset считывателя csv.

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

Ответ 2

Ваше решение на самом деле не так уж плохо. Переход итератора файла на нужную вам линию является хорошим подходом и используется во многих ситуациях, подобных этому.

Если вы хотите, чтобы это было более кратким, вы можете использовать next и enumerate с выражением :

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

Ответ 3

Вы можете просто сделать:

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)

Ответ 4

Модуль 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))

Ответ 5

Вы можете свести к минимуму ваш цикл 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)

Ответ 6

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