2016-10-24 2 views
0

Извините, если на самом деле есть простой ответ на этот вопрос. После двух дней поиска я его не нашел.Напишите список строк в списке, который может содержать или не содержать запятые для csv в Python

Я соскабливаю таблицу с сайта и строю список строк путем циклирования. Мой код отлично работает до тех пор, пока в одном из значений не будет запятой.

Это, как я строю список (зацикливание структура опущено, ясно):

record = (name, availability, upc, price) 
productList.append(",".join(item or "" for item in record)) 

Это приводит к:

[u'Product One, In Stock, 999999999999, $99.99', u'Product Two, In Stock, ....] 

Что я тогда пишу в CSV с:

import unicodecsv as csv 

... 

f = open('data.csv', 'wb') 
w = csv.writer(f, delimiter = ",") 
w.writerow([x.split(',') for x in productList]) 
f.close() 

Которая работает отлично вплоть до запятой в одном из названий продуктов. Неудивительно, что в этот момент название продукта прерывается несколькими столбцами.

Я ценю любую помощь, которую вы можете оказать. Спасибо.

+1

@UrielEli: Это просто означает, что если тильда появляется в поле, как правило, он преобразуется в запятую при чтении. Решение состоит в том, чтобы позволить модулю 'csv' выполнять свою работу, чтобы он обрабатывал цитирование для вас. – ShadowRanger

+0

@ShadowRanger: Спасибо! Я внедрил ваше предлагаемое редактирование в productList.append, а также настройку в раздел записи кода. (Как только мои тучные опечатки были исправлены) Это работало как чемпион! Спасибо. – NickV

ответ

2

Остановить вручную добавление и удаление запятых самостоятельно. Вот почему существуют модули csv/unicodecsv, потому что вы получите что-то вроде неправильного цитирования.

При создании ваших строк, делает их простые последовательности (list с или tuple S) полей, а не всю строку в виде одной строки:

productList.append([item or "" for item in record]) 
# If the or "" is to handle Nones only, module already handles this, so you can simplify: 
productList.append(record) 

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

with open('data.csv', 'wb') as f 
    w = csv.writer(f, delimiter = ",") 
    w.writerows(productList) 
    # writerows call is just faster way to do: 
    # for row in productList: w.writerow(row) 
+0

Если бы я знал, что правильный ответ настал бы так быстро, я бы спросил его вчера. – NickV

0

В вашей record переменного у вас уже есть кортеж, верно?

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

record = (name, availability, upc, price) 
productList.append(record) 

А затем используйте writerow метод unicodecsv писателя писать прямо кортеж в файле. В примере, показанном в packages's web page, он показывает, как писать кортеж. Пакет позаботится об обертывании строк, содержащих запятую с кавычками.

import unicodecsv as csv 

productList = [ 
    (u'Product One', u'In Stock', 999999999999, u'$99.99'), 
    (u'Product,Two', u'In Stock', 1234, u'$5.00'), 
    (u'Product Three', u'In Stock', 5678, u'$7.99'), 
] 

with open("foo.csv", "wb") as f: 
    w = csv.writer(f, encoding='utf-8') 
    for product in productList: 
     w.writerow(product) 

Это дает правильное foo.csv:

$ cat foo.csv 
Product One,In Stock,999999999999,$99.99 
"Product,Two",In Stock,1234,$5.00 
Product Three,In Stock,5678,$7.99 

(посмотреть, как "Product,Two" было правильно обернуты "?)

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