Чтение, форматирование, сортировка и сохранение csv-файла без панд

#python #csv #sorting

Вопрос:

Мне даны некоторые примеры данных в файле —> транзакции 1.csv >транзакции 1

Мне нужно написать код функции, которая будет выполнять следующее без использования панд:

  1. Откройте файл
  2. Отсортируйте столбец индекса в порядке возрастания
  3. Сохраните обновленные данные обратно в тот же файл

Это код, который у меня сейчас есть

 import csv

def sort_index():
    read_file=open("transactions1.csv","r")
    r=csv.reader(read_file)
    lines=list(r)
    sorted_lines=sorted(lines[1:], key=lambda row: row[0])
    read_file.close()
    
    with open('transactions1.csv','w',newline='') as file_writer:
        header=['Index','Day','Month','Year','Category','Amount','Notes'] #-
        writer=csv.DictWriter(file_writer, fieldnames=header)
        writer=csv.writer(file_writer)
        writer.writerows(sorted_lines)
        
    return False

sort_index()
 

Выходной ток:

 1,2,Dec,2021,Transport,5,MRT cost
10,19,May,2020,Transport,25,taxi fare
2,5,May,2021,investment,7,bill
3,2,Aug,2020,Bills,8,small bill
4,15,Feb,2021,Bills,40,phone bill
5,14,Oct,2021,Shopping,100,shopping 20
6,27,May,2021,Others,20,other spend
7,19,Nov,2019,Investment,1000,new invest
8,28,Mar,2020,Food,4,drink
9,18,Nov,2019,Shopping,15,clothes

 

Код, похоже, не работает, потому что индекс 10 появляется сразу после индекса 1. И заголовки отсутствуют.

Ожидаемый Результат:

 Index,Day,Month,Year,Category,Amount,Notes
1,2,Dec,2021,Transport,5,MRT cost
10,19,May,2020,Transport,25,taxi fare
2,5,May,2021,investment,7,bill
3,2,Aug,2020,Bills,8,small bill
4,15,Feb,2021,Bills,40,phone bill
5,14,Oct,2021,Shopping,100,shopping 20
6,27,May,2021,Others,20,other spend
7,19,Nov,2019,Investment,1000,new invest
8,28,Mar,2020,Food,4,drink
9,18,Nov,2019,Shopping,15,clothes

 

Комментарии:

1. Преобразуйте его в int ( int(row[0]) вместо row[0] ). Теперь вы сортируете строки.

2. Есть ли способ, чтобы заголовки также отображались в моих выходных данных?

3. да, звоните next(r) , также не нужно конвертировать в список

4. при следующей попытке(r) я получаю ошибку ValueError: недопустимый литерал для int() с основанием 10: ‘D’

Ответ №1:

В текущую функцию можно внести несколько улучшений.

Нет необходимости вызывать list reader объект, мы можем sort сделать это напрямую, так как он повторяется.

Мы можем извлечь заголовки из reader объекта, вызвав next непосредственно объект reader.

Это более удобно для обслуживания , если мы определяем пользовательскую ключевую функцию, которую не используем lambda , таким образом, если что-то изменится, необходимо изменить только определение функции.

Используйте with инструкцию для автоматической обработки закрытия объекта file.

 def _key(row):
    return int(row[0])

def sort_index():
    with open("transactions1.csv", "r") as fin:
        reader = csv.reader(fin)
        header = next(reader)
        rows = sorted(reader, key=_key)
    with open("transactions1.csv", "w", newline="") as fout:
        writer = csv.writer(fout)
        writer.writerow(header)
        writer.writerows(rows)