В принципе, я хочу перебирать файл и помещать содержимое каждой строки в глубоко вложенный dict, структура которого определяется количеством пробелов в начале каждой строки.Создание дерева/глубоко вложенного dict из текстового текстового файла с отступом в python
По существу, цель состоит в том, чтобы взять что-то вроде этого:
a
b
c
d
e
И превратить его в нечто вроде этого:
{"a":{"b":"c","d":"e"}}
Или это:
apple
colours
red
yellow
green
type
granny smith
price
0.10
в этом:
{"apple":{"colours":["red","yellow","green"],"type":"granny smith","price":0.10}
Чтобы я мог отправить его в модуль JSON Python и сделать JSON.
На данный момент я пытаюсь сделать Dict и список ступенчато, как например:
{"a":""} ["a"]
{"a":"b"} ["a"]
{"a":{"b":"c"}} ["a","b"]
{"a":{"b":{"c":"d"}}}} ["a","b","c"]
{"a":{"b":{"c":"d"},"e":""}} ["a","e"]
{"a":{"b":{"c":"d"},"e":"f"}} ["a","e"]
{"a":{"b":{"c":"d"},"e":{"f":"g"}}} ["a","e","f"]
т.д.
Список действует как «сухарей», показывая, где я в последний раз поставил в Словаре.
Для этого мне нужно пройти через список и создать что-то вроде dict["a"]["e"]["f"]
, чтобы добраться до последнего дикта. Я имел взгляд на класс AutoVivification, что кто-то сделал что выглядит очень полезно, однако я действительно уверен в:
- ли я, используя правильную структуру данных для этого (я планирую отправить это в библиотеку JSON для создания объекта JSON)
- Как использовать AutoVivification в этом случае
- Есть ли лучший способ в целом подойти к этой проблеме.
я придумал следующую функцию, но она не работает:
def get_nested(dict,array,i):
if i != None:
i += 1
if array[i] in dict:
return get_nested(dict[array[i]],array)
else:
return dict
else:
i = 0
return get_nested(dict[array[i]],array)
Оценил помощь!
(Остальная часть моей крайне неполном коды здесь :)
#Import relevant libraries
import codecs
import sys
#Functions
def stripped(str):
if tab_spaced:
return str.lstrip('\t').rstrip('\n\r')
else:
return str.lstrip().rstrip('\n\r')
def current_ws():
if whitespacing == 0 or not tab_spaced:
return len(line) - len(line.lstrip())
if tab_spaced:
return len(line) - len(line.lstrip('\t\n\r'))
def get_nested(adict,anarray,i):
if i != None:
i += 1
if anarray[i] in adict:
return get_nested(adict[anarray[i]],anarray)
else:
return adict
else:
i = 0
return get_nested(adict[anarray[i]],anarray)
#initialise variables
jsondict = {}
unclosed_tags = []
debug = []
vividfilename = 'simple.vivid'
# vividfilename = sys.argv[1]
if len(sys.argv)>2:
jsfilename = sys.argv[2]
else:
jsfilename = vividfilename.split('.')[0] + '.json'
whitespacing = 0
whitespace_array = [0,0]
tab_spaced = False
#open the file
with codecs.open(vividfilename,'rU', "utf-8-sig") as vividfile:
for line in vividfile:
#work out how many whitespaces at start
whitespace_array.append(current_ws())
#For first line with whitespace, work out the whitespacing (eg tab vs 4-space)
if whitespacing == 0 and whitespace_array[-1] > 0:
whitespacing = whitespace_array[-1]
if line[0] == '\t':
tab_spaced = True
#strip out whitespace at start and end
stripped_line = stripped(line)
if whitespace_array[-1] == 0:
jsondict[stripped_line] = ""
unclosed_tags.append(stripped_line)
if whitespace_array[-2] < whitespace_array[-1]:
oldnested = get_nested(jsondict,whitespace_array,None)
print oldnested
# jsondict.pop(unclosed_tags[-1])
# jsondict[unclosed_tags[-1]]={stripped_line:""}
# unclosed_tags.append(stripped_line)
print jsondict
print unclosed_tags
print jsondict
print unclosed_tags
я должен процитировать [Дзен Python] (http://www.python.org/dev/peps/pep-0020/) «Flat лучше, чем вложенное «. Я бы изменил, как вы это делаете. Всегда есть лучший способ, чем вложенные словари. Кроме того, убедитесь, что вы не попадаете в проблему [X Y] (http://meta.stackexchange.com/questions/66377/what-is-the-xy-problem). –
Мой оригинальный способ сделать это было довольно просто создать большую длинную строку, используя различные правила. Будет ли это лучше? – Tomcat
Это зависит от того, чего вы пытаетесь достичь, посмотрите на проблему [XY Problem] (http://meta.stackexchange.com/questions/66377/what-is-the-xy-problem) и убедитесь, что вы не делая подобной ошибки. По сути вам нужно выяснить, что вы DATA, и построить свой контейнер вокруг этого, а не строить контейнер и выяснить, как положить в него DATA. Каждый тип контейнера имеет свои преимущества, но использование строки для хранения разных наборов данных никогда не является хорошей идеей. –