Как пропустить пустые ячейки при создании словаря Python из CSV-файла?

У меня есть файл csv с такой структурой:

Name:   Tags:   col4    col4    col5    col6    col7
T1      G1      G2      G3      G4      G5  
T2      G1      G2              
T3      G1      G2      G3          
T4      G1      G2      G3      G4      G5      G6
T5      G1      G2      G3      G4      

В реальном файле 279 столбцов, и все строки имеют разную длину. Моя цель — получить каждое имя в качестве ключа, а затем соответствующие теги в виде списка значений в словаре Python.

Мой текущий код таков:

import csv

my_dict = {}
with open('infile.csv') as file:
    reader = csv.reader(file)
    for row in reader:
        my_dict[row[0]] = row[1:]
print(my_dict)

Это работает, но пустые ячейки включены как значения в словарь, например;

{T1: ['G1', 'G2', 'G3', 'G4', 'G5', ''], T2: ['G1', 'G2', '', '', '', ''] etc.

Принимая во внимание, что моя цель состоит в том, чтобы получить это:

{T1: ['G1', 'G2', 'G3', 'G4', 'G5'], T2: ['G1', 'G2'] etc.

Я не могу найти какой-либо вариант для csv.reader, который пропускает пустые ячейки. Я пробовал csv.DictReader (очевидно, это автоматически игнорирует пустые ячейки?), но он не разрешает срезы, и я не могу назвать и указать 279 столбцов.

Я знаю, что здесь есть похожие вопросы, но ни один из них не похож на то, что я ищу с точки зрения того, как я хочу, чтобы файл читался.

Я застрял на этом некоторое время, поэтому любая помощь будет высоко оценена.


person kor272    schedule 31.01.2018    source источник


Ответы (3)


Вы можете просто использовать понимание списка, чтобы выбрать непустые ячейки следующим образом:

import csv

my_dict = {}

with open('infile.csv', newline='') as f_input:
    csv_input = csv.reader(f_input)
    header = next(csv_input)   # skip over the header row

    for row in csv_input:
        my_dict[row[0]] = [cell for cell in row[1:] if cell]

print(my_dict)        

Предоставляем вам my_dict, содержащий:

{'T1': ['G1', 'G2', 'G3', 'G4', 'G5'], 'T2': ['G1', 'G2'], 'T3': ['G1', 'G2', 'G3'], 'T4': ['G1', 'G2', 'G3', 'G4', 'G5', 'G6'], 'T5': ['G1', 'G2', 'G3', 'G4']}

Примечание. При использовании Python 3.x файл следует открывать с помощью newline='' при использовании с объектом CSV.

person Martin Evans    schedule 31.01.2018

Вы можете использовать понимание списков.

import csv

my_dict = {}
with open('infile.csv') as file:
    reader = csv.reader(file)
    for row in reader:
        my_dict[row[0]] = [x for x in row[1:] if x!= ""]
print(my_dict)
person venky__    schedule 31.01.2018

Возможно, есть лучший способ, но вы можете добавить ключ, только если он есть, и отфильтровать результат.

import csv
my_dict = {}
with open('infile.csv') as file:
    reader = csv.reader(file)
    for row in reader:
        if row[0]:
            my_dict[row[0]] = list(filter(None, row[1:]))
print(my_dict)

в Python 2.7 фильтр возвращает непосредственно список, поэтому вы можете избежать вызова list для него.

редактировать: если подумать, в данных не должно быть совершенно пустой строки. Таким образом, вы, вероятно, можете удалить оператор if для строки [0].

person Hirabayashi Taro    schedule 31.01.2018
comment
Спасибо, похоже, это работает одинаково с оператором if или без него. - person kor272; 31.01.2018