2016-04-22 5 views
2

Я только начинаю с Python, и я работаю со следующим кодом, чтобы импортировать файл CSV в sqlite3 таблицу, которую я свободно признаться, я скопировал большую часть из интернета:Python: Как передать список как параметр функции?

with open(getPathTo('my.csv'), 'r') as csvfile: 
    reader = csv.DictReader(csvfile) 
    records = [(row['SEGMENT'], row['Comp 1'], row['Comp 2']) for row in reader] 
c.executemany("INSERT INTO comparison (`SEGMENT`, `Comp 1`, `Comp 2`) VALUES (?,?,?);", records) 
conn.commit() 

Он работает отлично, но я повторяю это для большого количества файлов и таблиц, и я хотел бы превратить его в функцию. Что я стремлюсь к что-то вроде:

def importCSVToTable(file, table, columns) 

Но, учитывая список columns, как я могу использовать его в этой строке:

records = [(row['SEGMENT'], row['Comp 1'], row['Comp 2']) for row in reader] 

Я просто немного Брошенный синтаксис, я думаю.

+0

Является ли количество столбцов и их имена меняющимися от таблицы к таблице? – alecxe

+0

Да. Различные таблицы с разными схемами. – Wintermute

+0

Вы считали ORM sqlalchemy? Благодарю. – alecxe

ответ

2

Вот пример кода, показывающий что-то, что может быть полезно. Мы используем вложенное понимание с оператором фильтрации if, чтобы убедиться, что мы не пытаемся получить доступ к несуществующим элементам dict.

In [3]: def importCSVtoTable(file, table, columns): 
    ...:  # 'mock' data to simulate a reader 
    ...:  reader = [{'SEGMENT': 2, 'Comp 1': 'dogs'}, {'Comp 2': 'cats', 'OTHERTHING': 4} 
    ...:  print [[row[label] for label in columns if label in row] for row in reader] 
    ...: 

In [4]: importCSVtoTable(None, None, ['SEGMENT', 'Comp 1']) 
[[2, 'dogs'], []] 

In [5]: importCSVtoTable(None, None, ['SEGMENT', 'Comp 1', 'Comp 2']) 
[[2, 'dogs'], ['cats']] 
+0

Это именно то, что я объяснил в своем ответе. +1 –

+1

Это именно то, что я хотел, спасибо! – Wintermute

-2

В функции получите список столбцов, а затем для каждого элемента в списке найдите row[list-element] и добавьте в список для записи.

+0

Это получает все столбцы; он, кажется, хочет, чтобы иметь возможность выбирать, который вытащил из CSV. –

+0

Нет, я думаю, он хочет вытащить все столбцы. –

+0

Нет, я хочу выбрать, какие из них вытащить, как указано в списке 'columns', я перейду в функцию. Я пытаюсь передать этот список столбцов в строку, которая заполняет переменную 'records' – Wintermute

0

возможно что-то вроде этого? конечно, непроверенный.

def importCSVToTable(conn, filename, table, columns) 
    with open(getPathTo(filename), 'r') as csvfile: 
     reader = csv.DictReader(csvfile) 
     records = [] 
     for row in reader: 
      for col in columns: 
       records.append(row[col]) 
    conn.executemany("INSERT INTO comparison (" + ','.join(columns) + ") VALUES ("+ ','.join(["?"]*columns.length) +");", records) 
    conn.commit() 
+0

Да, это сделало бы это, но я хотел, чтобы все это делалось на одной линии, что делает ответ выше. – Wintermute

+0

@Wintermute k. Но я чувствую, хотя, по-видимому, очень pythonic, забирая так много информации и поток управления в одну строку, не очень удобен в обслуживании. Но для каждого из его собственных я думаю – karina

1

Так что я думаю, что вы спрашиваете есть, учитывая список ключей (столбцы), как извлечь их из словаря? Давайте просто использовать файл CSV в памяти, чтобы проверить это:

>>> example_data = """col1,col2,col3\na1,a2,a3\nb1,b2,b3\nc1,c2c3""" 
>>> print example_data 
col1,col2,col 
a1,a2,a3 
b1,b2,b3 
c1,c2c3 

Тогда, если мы имеем CSVReader, основанный на том, что:

>>> import csv, StringIO 
>>> reader = csv.DictReader(StringIO.StringIO(example_data)) 
>>> print reader.fieldnames 
['col1', 'col2', 'col3'] 

Таким образом, если мы хотим перебрать на основе этого списка поля:

>>> for row in reader: 
...  print 'insert into mytable (%s) values (%s)' % (','.join(reader.fieldnames), ','.join(['?']*len(reader.fieldnames))) 
insert into mytable (col1,col2,col3) values (?,?,?) 
insert into mytable (col1,col2,col3) values (?,?,?) 
insert into mytable (col1,col2,col3) values (?,?,?) 

Оттуда, очевидно, вы захотите адаптировать его для своей функции. Но отвечает ли это на ваш вопрос о механизме csvreader и манипулирует списками Python?

(Примечание, это для Python 2.)

+0

Это не совсем то, что я искал - я хотел посмотреть, смогу ли я адаптировать одну строку в моем существующем коде для работы со списком, но это, безусловно, полезно, тем не менее, спасибо. – Wintermute

Смежные вопросы