Чтение и разделение файла .csv, который содержит строки с запятыми в

#python #string #csv #split

#python #строка #csv #разделение

Вопрос:

У меня есть файл .csv, который выглядит примерно так:

 1,2,"a,b",3
4,"c,d",5,6
 

Которые я читаю и сохраняю в массиве, подобном этому:

 with open(filename, 'r') as f:
    data = f.readlines()
data = [line.split(',') for line in data]
 

В результате получается такой массив:

 [['1','2','"a','b"','3']['4','"c','d"','5','6']]
 

ОДНАКО я хотел бы сохранить элементы в двойных кавычках, такие как «a, b», в одном элементе массива данных (именно так они открываются в Excel), например:

 [[1,2,'a,b',3][4,'c,d',5,6]]
 

Есть ли простой способ добиться этого в Python?

Редактировать: желательно без использования модуля csv, если это возможно?

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

1. Вы можете использовать модуль csv

2. Или вы также можете реализовать свой собственный синтаксический анализатор

3. @dcg Я пытался избежать использования этого, чтобы все было чисто и просто, но если это единственный способ…

4. Я думаю, что проще использовать csv , чем делать это самостоятельно

5. Использование csv модуля, который является частью стандартной библиотеки, действительно лучший выбор здесь. Он прост в использовании (см. Мой Ответ, используя его ниже), И вы можете быть уверены, что все возможные проблемы, подобные этой, кавычки и т. Д., Были правильно решены и что вы не столкнетесь с ошибкой в каком-то угловом случае.

Ответ №1:

Вы должны использовать csv модуль:

 import csv

with open('test.csv') as f:
    reader = csv.reader(f)
    
    for row in reader:
        print(row)
 

Вывод:

 ['1', '2', 'a,b', '3']
['4', 'c,d', '5', '6']
 

Или, если вы не хотите лениво читать строки и хотите, чтобы все было в одном списке, как в вашем вопросе, вы можете просто сделать:

 with open('test.csv') as f:
    reader = csv.reader(f)
    data = list(reader)

print(data)        
# [['1', '2', 'a,b', '3'], ['4', 'c,d', '5', '6']]   
 

Ответ №2:

Использование csv модуля:

 import csv

with open('test.csv') as file:
    reader = csv.reader(file)
    
data = [row for row in reader]
 

Ответ №3:

если вы не хотите использовать csv module, эта функция вернет желаемый результат

 def function(file_name):
    with open(file_name, 'r') as file:
        file_read = file.readlines()
        raw_data = [line.split(',') for line in file_read]

        file_data = list()
        place_0 = 0
        place_1 = 0
        ext_item = str()
        added = list()
        pre_final_list = list()
        pre_pure_list = list()
        pure_data = str()
        final_list = list()

        for List in raw_data:
            for k, v in enumerate(List):
                List[k] = v.rstrip()
        
        for line in raw_data:
            if line == ['']:
                continue
            file_data.append(line)

        for line in file_data:
            for key, value in enumerate(line):
                if '"' in value[0] and '"' in value[-1]:
                    continue
                if '"' in value[0]:
                    place_0 = key
                if '"' in value[-1]:
                    place_1 = key
                if place_1 != 0:
                    for ind in range(place_0, place_1 1):
                        added.append(line[ind])
                    for e_item in added:
                        if e_item == added[-1]:
                            ext_item  = e_item
                        else:
                            ext_item  = e_item   ','
                    line[place_0] = ext_item
                    for r_item_index in range(place_0 1, place_1 1):
                        line[r_item_index] = None
                    place_0 = 0
                    place_1 = 0
                    ext_item = str()
                    added = list()

        for line in file_data:
            for value in line:
                try:
                    value = int(value)
                except: 
                    pass
                if value == 'n':
                    continue
                if not value is None:
                    pre_pure_list.append(value)
            pre_final_list.append(pre_pure_list)
            pre_pure_list = list()
        

        for List in pre_final_list:
            for key, item in enumerate(List):
                if type(item) is int or '"' not in item:
                    continue
                for string in item:
                    if string == '"':
                        continue
                    pure_data  = string
                List[key] = pure_data
                pure_data = str()
            final_list.append(List)