Этот вопрос задавали раньше, но в моем случае ни один из ответов не применяется.
Я читаю csv файл с этим:
with codecs.open('./products.csv', 'r', encoding="utf-8") as _filehandler:
csv_file_reader = csv.DictReader(_filehandler)
for row in csv_file_reader:
в моем CSV файле у меня есть столбец в строке, который содержит это:
'#custom_shrink_wrapping': '700', '#custom_green_paper': '338'
моя цель - добавить это к dict. Вышеуказанный столбец находится в одном столбце.
Вот пример данных:
item,parse_dropdowns,fixed_dropdowns_values,links
postcards,"#quantity, #paper, #size, #color, #turnaround, #coating","‘#custom_finishing': '497', '#custom_shrink_wrapping': '700', '#custom_green_paper': '338'",http://www.example.com/products/postcards
flyers,"#quantity, #paper, #size, #color, #turnaround, #coating, #folding","‘#custom_green_paper': '338', '#custom_hole_punch': '204', '#custom_shrink_wrapping': '700'",http://www.example.com/products/brochures
brochures,"#quantity, #paper, #size, #color, #turnaround, #coating, #folding","‘#custom_green_paper': '338', '#custom_hole_punch': '204', '#custom_shrink_wrapping': '700'",http://www.example.com/products/brochures
business cards,"#quantity, #paper, #size, #color, #turnaround, #coating","‘#custom_green_paper': '338', '#custom_shrink_wrapping': '700', '#versionCustomerPulldown': '1'",http://www.example.com/products/businesscards
bookmarks,"#quantity, #paper, #size, #color, #turnaround, #coating","‘#custom_finishing': '497', '#custom_shrink_wrapping': '700', '#custom_green_paper': '338'",http://www.example.com/products/bookmarks
calendars,"#quantity, #paper, #size, #color, #turnaround, #page, #coating","‘#custom_green_paper': '338', '#custom_finishing': '13356', '#custom_hole_punch': '205', '#custom_shrink_wrapping': '700'",http://www.example.com/products/calendars
Конечной целью было бы сделать следующее:
{'#custom_shrink_wrapping': '700', '#custom_green_paper': '338'}
Я думал, что это будет так же просто, как это сделать:
dropdownValuesCsv = dict()
dropdownValuesCsv.append( row['fixed_dropdowns_values'] )
Это не удалось. Затем я попробовал это:
dropdownValuesCsv = dict()
dropdownValuesCsv.update( row['fixed_dropdowns_values'] )
Это вызвало эту ошибку:
ValueError: dictionary update sequence element #0 has length 1; 2 is required
Затем я попробовал это:
dropdownValuesCsv = { row['fixed_dropdowns_values'] }
но это создает набор, который дает ошибку и не то, что я ищу.
Изменить: Измененный код для использования ast.literal_eval()
вместо более мощного (и потенциально более опасного) встроенного eval()
потому что он безопаснее, чем все, что здесь нужно.
Обратите внимание, что для тестирования я создал products.csv
файл данных, который вы добавили на свой вопрос, хотя я должен был изменить '
символы в нем в '
голец в результате в нем, содержащем это (потому что в противном случае чтения файла результатов в codec
ошибке):
item,parse_dropdowns,fixed_dropdowns_values,links
postcards,"#quantity, #paper, #size, #color, #turnaround, #coating","'#custom_finishing': '497', '#custom_shrink_wrapping': '700', '#custom_green_paper': '338'",http://www.example.com/products/postcards
flyers,"#quantity, #paper, #size, #color, #turnaround, #coating, #folding","'#custom_green_paper': '338', '#custom_hole_punch': '204', '#custom_shrink_wrapping': '700'",http://www.example.com/products/brochures
brochures,"#quantity, #paper, #size, #color, #turnaround, #coating, #folding","'#custom_green_paper': '338', '#custom_hole_punch': '204', '#custom_shrink_wrapping': '700'",http://www.example.com/products/brochures
business cards,"#quantity, #paper, #size, #color, #turnaround, #coating","'#custom_green_paper': '338', '#custom_shrink_wrapping': '700', '#versionCustomerPulldown': '1'",http://www.example.com/products/businesscards
bookmarks,"#quantity, #paper, #size, #color, #turnaround, #coating","'#custom_finishing': '497', '#custom_shrink_wrapping': '700', '#custom_green_paper': '338'",http://www.example.com/products/bookmarks
calendars,"#quantity, #paper, #size, #color, #turnaround, #page, #coating","'#custom_green_paper': '338', '#custom_finishing': '13356', '#custom_hole_punch': '205', '#custom_shrink_wrapping': '700'",http://www.example.com/products/calendars
Здесь код, который может читать и делать то, что вы хотите:
import ast
import codecs
import csv
COL_NAME = 'fixed_dropdowns_values' # Column of interest.
with codecs.open('./products.csv', 'rb', encoding="utf-8") as _filehandler:
csv_file_reader = csv.DictReader(_filehandler)
for row in csv_file_reader:
dropdownValuesCsv = ast.literal_eval('{' + row[COL_NAME] + '}')
print(dropdownValuesCsv)
И здесь словари, которые он создает и печатает во время чтения (измененного) ввода:
{'#custom_finishing': '497', '#custom_green_paper': '338', '#custom_shrink_wrapping': '700'}
{'#custom_hole_punch': '204', '#custom_shrink_wrapping': '700', '#custom_green_paper': '338'}
{'#custom_hole_punch': '204', '#custom_shrink_wrapping': '700', '#custom_green_paper': '338'}
{'#versionCustomerPulldown': '1', '#custom_shrink_wrapping': '700', '#custom_green_paper': '338'}
{'#custom_finishing': '497', '#custom_green_paper': '338', '#custom_shrink_wrapping': '700'}
{'#custom_hole_punch': '205', '#custom_finishing': '13356', '#custom_shrink_wrapping': '700', '#custom_green_paper': '338'}
print("eval('{' + row[COL_NAME] + '}')")
, вы должны увидеть вывод, похожий на тот, что показан в моем ответе.
Я думаю, что в вашей проблеме есть только путаница, которая поможет вам разобраться.
Во-первых, мне непонятно, когда вы говорите, что ваш CSV имеет один столбец со значением '#custom_shrink_wrapping': '700', '#custom_green_paper': '338'
, так как это включает запятую (и вы не указали другой разделитель), так что это должно быть два столбца?Я отвечу на ваш вопрос с предположением, что это заменит другой разделитель (скажем, точка с запятой). Изменение: с тех пор это стало ясно с добавленным скриншотом.
Я считаю, что основная проблема заключается в том, что вы не рассматриваете тип вывода csv.DictReader
. Когда он анализирует ваш csv, он будет отображать ключи в строки, поэтому, когда вы пытаетесь обновить словарь с его выводом, вы не получите несколько значений, которые вы хотите (только одна строка, которая подразумевает эти значения). Однако мы можем обойти это, проанализируя строки.
Вот мой рабочий пример:
tmp.csv
fixed_dropdown_values, other
"'#custom_shrink_wrapping': '700', '#custom_green_paper': '338'", 'other': 'other'
test.py
import csv
dropdownValuesCSV = {}
with open('./tmp.csv') as file_handler:
reader = csv.DictReader(file_handler)
for row in reader:
# We split multiple key-value pairs by comma
for mapping in row['fixed_dropdown_values'].split(','):
# We do an additional split on a colon to differentiate keys and values
# ... and do some extra cleanup to remove extra spaces and quotation marks
key, val = [s.strip(' ').replace("'", '') for s in mapping.split(':')]
dropdownValuesCSV[key] = val
print dropdownValuesCSV
# dropdownValuesCSV is:
# {'#custom_green_paper': '338', '#custom_shrink_wrapping': '700'}
Надеюсь, это поможет.
products.csv
(включая начальную строку заголовка).