Импортировать строку CSV в DICT?

1

Этот вопрос задавали раньше, но в моем случае ни один из ответов не применяется.

Я читаю 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'] }

но это создает набор, который дает ошибку и не то, что я ищу.

  • 0
    Пожалуйста, отредактируйте ваш вопрос и добавьте несколько строк примеров данных из файла products.csv (включая начальную строку заголовка).
  • 0
    @martineau Хорошо, я добавил снимок экрана с CSV. Спасибо, что взглянули на это!
Показать ещё 1 комментарий
Теги:
python-2.7

2 ответа

0
Лучший ответ

Изменить: Измененный код для использования 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'}
  • 0
    для меня странно, что это просто отправляет это на мою консоль: print (eval ('{' + row ['fixed_dropdowns_values'] + '}'))
  • 0
    Похоже, что строка печати была изменена на print("eval('{' + row[COL_NAME] + '}')") , вы должны увидеть вывод, похожий на тот, что показан в моем ответе.
Показать ещё 2 комментария
0

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

Во-первых, мне непонятно, когда вы говорите, что ваш 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'}

Надеюсь, это поможет.

  • 0
    Данные на самом деле в одном столбце. Я просто добавил снимок экрана с данными. @Baozi
  • 0
    В этом случае читатель по-прежнему будет выводить одну большую строку (только с разделителем запятых), так что вы можете просто заменить точку с запятой в моем ответе, и она все равно должна работать.
Показать ещё 3 комментария

Ещё вопросы

Сообщество Overcoder
Наверх
Меню