2015-09-30 3 views
-1

У меня есть список, состоящий из строк, целых чисел и плавающих элементов, а также вложенных списков строк, целых чисел и поплавков. Вот примерPython сохраняет произвольно вложенный список в CSV

data = [ 
     1.0, 
     'One', 
     [1, 'Two'], 
     [1, 'Two', ['Three', 4.5]], 
     ['One', 2, [3.4, ['Five', 6]]] 
    ] 

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

1.0 
One 
1,Two 
1,Two,Three,4.5 
One,2,3.4,Five,6 

Есть много ресурсов о том, как составить список в файл, но я не видел ни что делать независимо из вложенность списка. Я уверен, что могу придумать что-то, что связано с множеством циклов и т. Д., Но есть ли у кого-нибудь более элегантное решение?

EDIT: Лучшая вещь, которую я придумал, состоит в том, чтобы преобразовать каждый элемент в список в строку, а затем удалить дополнительные символы ("[", "]" и т. Д.). Затем прикрепите ниточки запись и записать результат в файл:

string = '' 
for i in data: 
    line = str(i).replace("[","") 
    line = line.replace("]","") 
    line = line.replace("'","") 
    line = line.replace(" ","") 
    string+=line + '\n' 

# write string to file... 

Это просто чувствует kludgey, и это потенциально вредно, поскольку это предполагает, что строки не содержат скобки, кавычки, или пробелы. Я ищу лучшее решение!

+0

Пожалуйста, покажите нам, что вы пробовали. Если вы не знаете, как только вы начнете в направлении, кто-то может помочь вам придумать точное решение. Infact, это не должно быть так сложно. Откройте файл csv в режиме записи и в цикле начните запись в файл. – karthikr

+0

Более элегантное решение * чем то, что *? Покажите, что вы пробовали ... –

+2

Я думаю, что это проще всего сгладить каждый элемент первым (http://stackoverflow.com/questions/10823877/what-is-the-fastest-way-to-flatten-arbitrarily-nested -lists-in-python), а затем сохранить в csv. – zehnpaard

ответ

3

То, что вы просите, более или менее невозможно.

CSV - это плоский табличный формат хранения. Иерархический характер «произвольно вложенных списков» просто не соответствует или хорошо вписывается в табличную структуру.

Вы можете определенно сгладить вложенный список, чтобы каждый элемент первого уровня вашего вложенного списка появлялся в одной строке выходного файла. Но это не CSV, строго говоря. Некоторые читатели CSV могут правильно читать данные, а другие - нет. И, как только вы сглаживаете, как в вашем примере, вы никогда не сможете восстановить исходный список, прочитав файл.

Демонстрация:

[1, ["Two", "Three"], 4.0] 

и

[1, ["Two", ["Three"]], 4.0] 

оба будут испускать:

1 
Two,Three 
4.0 

Так что на чтение этого файла, читатель/анализатор не будет знать, какой из оригинала списки для возврата - первый, двухуровневый список или второй, трехуровневый список. (Я могу сделать этот встречный пример сколь угодно сложным и уродливым.)

В целом, вложенные/иерархические структуры и плоские/табличные структуры просто нелегко или полностью совместимы.

Если вы хотите получить простой формат хранения для произвольно вложенного списка, рассмотрите JSON или YAML. Они обеспечивают легкое, высококачественное хранилище для вложенных данных. Например:

будет записывать ваши данные в файл.Чтобы прочитать его обратно в:

data = json.load(open(out path)) 

Но если вы действительно хотите CSV-иш текст:

def flatten(l): 
    """ 
    Flatten a nested list. 
    """ 
    for i in l: 
     if isinstance(i, (list, tuple)): 
      for j in flatten(i): 
       yield j 
     else: 
      yield i 

def list2csv(l): 
    """ 
    Return CSV-ish text for a nested list. 
    """ 
    lines = [] 
    for row in l: 
     if isinstance(row, (list, tuple)): 
      lines.append(",".join(str(i) for i in flatten(row))) 
     else: 
      lines.append(str(row)) 
    return "\n".join(lines) 

print list2csv(data) 

Урожайность:

1.0 
One 
1,Two 
1,Two,Three,4.5 
One,2,3.4,Five,6 
+0

Я знаю, если несовместимость двух форм. Однако для моих целей исходная структура вложенного списка несущественна (произвольно, фактически). –

+0

Тогда может работать сглаживающий подход. Это немного более непосредственная работа, чем использование существующего модуля ввода-вывода, такого как 'json', и это еще не очень хорошо сформированный CSV, но вы можете избежать большинства проблем с выравниванием. –

+0

Хорошо, поэтому я добавил код list-flatten-to-CSV. Это не идеально, но он будет делать то, что вы просили. –

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