Python:将嵌套JSON写入列表中的多个元素 [英] Python: Write Nested JSON as multiple elements in List
问题描述
我想做什么:导入Json字符串/文件并将其写入数据库。有多种组合的输入(汽车)。最低嵌套的dict / list定义了一个列在DB中的元素的数量。
这里是JSON / String:
input = [{id:BMW_1_Series,
years:[{id:10052,year 2008,
styles:[{id:560,name:128i 2,
submodel:{body:Conver,niceName ,trim:128i},
{id:561,name:135i,
submodel:{body:Conver :conver},trim:135i}
]
},
{id:427,year:2016,
styles :[{id:433,name:228i,
submodel:{body:Conve,niceName:conver},trim:228i SULEV },
{id:431,name:M235i,
submodel:{body:Coupe,niceName:m235i},trim : M235i }
]
}
]
}
#I删除其他条目,但它是一个列表
]
输出应该是一个dict,一个子表的键应该是子键的前缀:
{'id':427,'year':2016,'styles_id':431,'styles_name':'M235i','styles_trim' M235i','submodel_body':'Coupe','submodel_niceName':'m235i'}
它从几年前开始工作:
在几年中:#styles
outputA = {}
对于说明符A,s.items()中的valueA:
如果isinstance(valueA,列表):$ a
如果为A,则
如果isinstance(A,dict):
outputB = {}
for specifierB,valueB在A.items()中:#submodel
if isinstance(valueB,dic t):
for specifierBB,valueBB in valueB.items():
outputA [specifierB +__+ specifierBB] = valueBB
else:
outputA [specifierA +_+ specifierB] = valueB
else:
outputA [specifierA] = valueA
elif isinstance(valueA,dict):
outputB = {}
for specifierB在valueA.items()中的valueB:#submodel
outputA [specifierA +_+ specifierB] = valueB
else:
outputA [specifierA] = valueA
print(str输出A))
output.append(outputA)
我在这里停下来,关于如何读取含有dicts,list和normal值的JSON文件的一般情况。
我的方法到目前为止(它不工作,我花了三天时间...(我删除所有的中间打印,以便阅读) *注意:CODE是一个连续循环...
def readL(input,prefix =):
/ pre>
x = True
output = {}
k = 0
while(x):
k + = 1
x = False
if isinstance(input,list)
print(LIST:+ str(input))
for a in input:
if isinstance(A,dict):
output = dict(output,** readL (A))
elif isinstance(A,list):
output = dict(output,** readL(A))
elif isinstance(input,dict):
for specifier B,input.items()中的valueB:#submodel
如果isinstance(valueB,dict):
specifierB = str(specifierB)+_
output = dict(output,** readL(valueB,specifierB))
如果isinstance(valueB,list):
specifierB = str(specifierB)+_
output = dict(output,** readL lueB,specifierB))
spec = prefix + specifierB
output [spec] = valueB
#check如果Output Dict包含列表或Dict - >继续循环
为specifierT,valueT在output.items()中:
如果isinstance(valueT,dict)或isinstance(valueT,list):
x = True
如果k == 1:#我有一个继续循环到目前为止,这就是为什么
break
return(output)
readL(test)
基本上,我想有一个递归函数,继续调用自己,直到输出中没有dict / list。
我也可以使用任何其他更快的方法来阅读输入。
我非常期待一些建议。请忍受我,我对Python很新。
感谢一下!
更新
我发现了一个部分解决方案,在平铺Python中的Python或列表的通用JSON列表从@poke
def splitObj(obj,prefix = None):
'''
拆分对象,返回一个带有平面对象的3元组,可选的是
,后面是子对象和这些子对象的列表。
'''
#复制对象,可选地在每个键之前添加前缀
new = obj.copy(),如果前缀为无{{} _ {}'。format前缀,k):v for k,v in obj.items()}
#尝试找到保存子对象的键或子对象的列表
for k,v in new。 item():
#子对象的列表
如果isinstance(v,list):
del new [k]
return new,k,v
#或just一个子对象
elif isinstance(v,dict):
del new [k]
return new,k,[v]
return new,None,none
def flatten(数据,前缀=无):
'''
平滑数据,可选地每个键前缀。
'''
#对数据中的项目迭代所有项
#拆分对象
flat,key,subs = splitObj(item,prefix)
#只返回完全平面对象
如果键为None:
yield flat
continue
#否则递归地平铺子对象
(sub,key):
sub.update(flat)
yield sub
但是由于我的输入有所改变:
input = [{'states':[' US $'$'$''''''''''''''''''''''''''' ''''',''''''''''''''''''''''''''''''''' '128i 2dr敞篷车(3.0L 6cyl 6M)','id':100994560},
{'trim':'128i','states':['USED'],'submodel':{'body':'Coupe','niceName ':'coupe','modelName':'1 Series Coupe'},
'name':'128i 2dr Coupe(3.0L 6cyl 6M)','id':100974974},
{' ''''''''''''',$'''''''''''','''' b $ b'name':'135i 2dr Coupe(3.0L 6cyl Turbo 6M)','id':100974975},
{'trim':'135i','states':['USED'], 'submodel':{'body':'Convertible','niceName':'convertible','modelName':'1 Series Convertible'},
'name':'135i 2dr Convertible(3.0L 6cyl Turbo 6M )','id':100994561}
],
'state':['USED'],'id':100524709,'year':2008},
{'styles':
[{'trim':'135i','states' ['USED'],'submodel':{'body':'Coupe','niceName':'coupe','modelName':'1 Series Coupe'},
'name':'135i 2dr Coupe (3.0L 6cyl Turbo 6M)','id':101082656},
{'trim':'128i','states':['USED'],'submodel':{'body' ','niceName':'coupe','modelName':'1 Series Coupe'},
'name':'128i 2dr Coupe(3.0L 6cyl 6M)','id':101082655},
{'trim':'135i','states':['USED'],'submodel':{'body':'Convertible','niceName':'convertible','modelName':'1 Series Convertible '},
'name':'135i 2dr Convertible (3.0L 6cyl Turbo 6M)','id':101082663},
{'trim':'128i','states':['USED'],'submodel':{'body' ','niceName':'convertable','modelName':'1 Series Convertible'},
'name':'128i 2dr Convertible(3.0L 6cyl 6M)','id':101082662}
],
'states':['USED'],'id':100503222,'year':2009},
{'style':
[{'trim' 128i','states':['USED'],'submodel':{'body':'Coupe','niceName':'coupe','modelName':'1 Series Coupe'},
'名称':'128i 2dr Coupe(3.0L 6cyl 6M)','id':101200599},
{'trim':'135i','states':['USED'],'submodel' 'body':'Coupe','niceName':'coupe','modelName' :'1系列Coupe'},
'name':'135i 2dr Coupe(3.0L 6cyl Turbo 6M)','id':101200600},
{'trim':'135i','状态':['USED'],'submodel':{'body':'Convertible','niceName':'convertible','modelName':'1 Series Convertible'},
'name' 135i 2dr Convertible(3.0L 6cyl Turbo 6M)','id':101200607},
{'trim':'128i','states':['USED'],'submodel' :'Convertible','niceName':'convertable','modelName':'1 Series Convertible'},
'name':'128i 2dr Convertible(3.0L 6cyl 6M)','id':101200601}
],
'states':['USED'],'id':100529091,'year':2010},
{'styles':
[{'trim ':'128i ,'状态':''''''''''''''''''''''''''''''''''''' :'128i 2dr Coupe(3.0L 6cyl 6M)','id':101288165},
{'trim':'135i','states':['USED'],'submodel' ':'Coupe','niceName':'coupe','modelName':'1 Series Coupe'},
'name':'135i 2dr Coupe(3.0L 6cyl Turbo 6M)','id' 10128166},
{'trim':'135i','states':['USED'],'submodel':{'body':'Convertible','niceName':'convertible','modelName' :'1 Series Convertible'},
'name':'135i 2dr Convertible(3.0L 6cyl Turbo 6M)','id':101288298},
{'trim':'128i'国家':['USED'],'submodel':{'body':'Convertible ,'niceName':'convertable','modelName':'1 Series Convertible'},
'name':'128i 2dr Convertible(3.0L 6cyl 6M)','id':101288297}
],
'states':['USED'],'id':100531309,'year':2011},
{'style':
[{'trim':'128i ''''''''''''''''$'$'','''''''''''''''''''' ':'128i 2dr Convertible(3.0L 6cyl 6M)','id':101381667},
{'trim':'135i','states':['USED'],'submodel'身份':'Convertible','niceName':'convertible','modelName':'1 Series Convertible'},
'name':'135i 2dr Convertible(3.0L 6cyl Turbo 6M)','id' :10 1381668},
{'trim':'128i','states':['USED'],'submodel':{'body':'Coupe','niceName':'coupe','modelName' :'1 Series Coupe'},
'name':'128i 2dr Coupe(3.0L 6cyl 6M)','id':101381665},
{'trim':'135i','states ':['USED'],'submodel':{'body':'Coupe','niceName':'coupe','modelName':'1 Series Coupe'},
'name':'135i 2dr Coupe(3.0L 6cyl Turbo 6M)','id':101381666}
],
'states':['USED'],'id':100534729,'year':2012}
{'style':
[{'trim':'128i','states':['USED'],'submodel':{'body':'Coupe','niceName' 'coupe','modelName':'1 Series Coupe'},
'name':'128i 2dr Coupe(3.0L 6cyl 6M)','id':200428722},
{'trim':'128i','states':['USED'],'submodel' {'body':'Convertible','niceName':'convertible','modelName':'1 Series Convertible'},
'name':'128i 2dr Convertible(3.0L 6cyl 6M)','id ':200428721},
{'trim':'135is','states':['USED'],'submodel':{'body':'Coupe','niceName':'coupe' modelName':'1 Series Coupe'},
'name':'135is 2dr Coupe(3.0L 6cyl Turbo 6M)','id':200421701},
{'trim':'135i' ,'状态':''''''''''''''''''''''''''''''''''''' :'135i 2dr Coupe(3.0L 6cyl Turbo 6M)','id':200428724},
{'trim':'135i','states':['USED'],'submodel':{'body':'Convertible','niceName':'convertible','modelName'系列可转换'},
'name':'135i 2dr Convertible(3.0L 6cyl Turbo 6M)','id':200428723},
{'trim':'128i SULEV' :['USED'],'submodel':{'body':'Coupe','niceName':'coupe','modelName':'1 Series Coupe'},
'name':'128i SULEV 2dr Coupe(3.0L 6cyl 6M)','id':200428726},
{'trim':'128i SULEV','states':['USED'],'submodel' 'Convertible','niceName':'convertable','modelName':'1 Series Convertible'},
'name':'128i SULEV 2dr Convertible(3.0L 6cyl 6M)','id':200428725} ,
{'t '''''''''''','''''''''''''''''''''' b $ b'name':'135is 2dr Convertible(3.0L 6cyl Turbo 6M)','id':200428727}
],
'states':['USED'],'id' 200421700,'year':2013}
],
'name':'1 Series','make':{'niceName':'bmw','name':'BMW' ':200000081}
}]
但是我收到错误:
AttributeError:'str'对象没有属性'update'
因为它不处理
'states':['USED']
我认为
我可以做些什么?
我把这个问题转移到了将嵌套的JSON(Dict,List)放入列表以准备写入数据库
请在那里发表评论。谢谢!解决方案如果我正确理解你的意图,那么你正在尝试平铺你的JSON,但是只有当你遇到某个键或键。如果是这样,你可以尝试这样:
给定:
来自pprint import pprint
input_list = [{id:BMW_1_Series,
years:[{id:10052,year:2008,
style:[{id:560,name:128i 2,
submodel:{body:Conver,niceName :128i},
{id:561,name:135i,
submodel:{body:Conver,niceName:conver ,trim:135i}
]
},
{id:427,year:2016,
styles:[{id :433,name:228i,
submodel:{body:Conve,niceName:conver},trim:228i SULEV},
id:431,name:M235i,
submodel:{body:Coupe,niceName:m235i},trim:M235i}
]
}
]
}
#I删除其他条目,但它是一个列表
]
使用以下功能:
def flatten(something,parent_key = None) :
如果parent_key == None:
prefix =
else:
prefix = parent_key +_
如果type(something)==键入({}):
temp = {}
在某些东西:
temp.update(flatten(东西[key],前缀+键))
return temp
elif type(something)== type([]):
temp = {}
范围内的索引(len(something)):
temp.update(flatten(something [index],prefix + str(index)))
#temp.update(flatten(something [index],prefix + str(something [index] ['id']) ))
return temp
else:
return {parent_key:something}
def somet_flatten(something,flatten_键$)
如果类型(东西)==类型({}):
temp = {}
为某些东西:
如果键在flatten_keys:
temp.update(flatten(something [key],key))
else:
temp.update({key:somet_flatten(something [key],flatten_keys)})
return temp
elif type(something)== type([]):
return [some_flatten(x,flatten_keys)for x in something]
else:
返回一些
然后在这里打电话给他们:
如果__name __ =='__ main__':
flatten_keys = ['years']
a = somet_flatten(input_list,flatten_keys)
pprint(a)
但是您可以将任何键放入
flatten_keys
变量来改变它的行为以及它会做多大的变化after two almost three days of programming, I am seeking for help.
What I want to do: Import Json string/ file and write it to a database. There are multiple combination of the input (cars). To lowest nested dict/ list defines the number of elements of a list which will be written in the DB.
Here is the JSON/ String:
input = [{"id":"BMW_1_Series", "years":[{"id":10052,"year":2008, "styles":[{"id":560,"name":"128i 2", "submodel":{"body":"Conver","niceName":"conve"},"trim":"128i"}, {"id":561,"name":"135i ", "submodel":{"body":"Conver","niceName":"conver"},"trim":"135i"} ] }, {"id":427,"year":2016, "styles":[{"id":433,"name":"228i ", "submodel":{"body":"Conve", "niceName":"conver"},"trim":"228i SULEV"}, {"id":431,"name":"M235i", "submodel":{"body":"Coupe", "niceName":"m235i"},"trim":"M235i"} ] } ] } #I deleted the other entries, but it is a list ]
The output should be a dict and the keys for a subdict should be a prefix for the sub-key:
{'id': 427, 'year': 2016, 'styles_id': 431, 'styles_name': 'M235i', 'styles_trim': 'M235i', 'submodel_body': 'Coupe', 'submodel_niceName': 'm235i'}
I got it to work from years onwards:
for s in years:#styles outputA ={} for specifierA, valueA in s.items(): if isinstance(valueA, list): for A in valueA: if isinstance(A, dict): outputB = {} for specifierB, valueB in A.items(): #submodel if isinstance(valueB, dict): for specifierBB, valueBB in valueB.items(): outputA[specifierB+"__"+specifierBB]= valueBB else: outputA[specifierA+"_"+specifierB]= valueB else: outputA[specifierA] = valueA elif isinstance(valueA, dict): outputB = {} for specifierB, valueB in valueA.items(): #submodel outputA[specifierA+"_"+specifierB]= valueB else: outputA[specifierA] = valueA print(str(outputA)) output.append(outputA)
I stoped here as I wanted to have a general case on how to read JSON files containing dicts, list and normal values.
My approach for that so far (it is not working and I spent three days on it... (I delted all the intermediate prints for easier reading) *Note: COde is a continuous loop...
def readL(input, prefix=""): x = True output={} k=0 while (x): k+=1 x=False if isinstance(input, list): print("LIST: "+str(input)) for A in input: if isinstance(A, dict): output = dict(output, **readL(A)) elif isinstance(A, list): output = dict(output, **readL(A)) elif isinstance(input, dict): for specifierB, valueB in input.items(): #submodel if isinstance(valueB, dict): specifierB = str(specifierB)+"_" output = dict(output, **readL(valueB,specifierB)) if isinstance(valueB, list): specifierB = str(specifierB)+"_" output = dict(output, **readL(valueB,specifierB)) spec = prefix+specifierB output[spec] = valueB #check if Output Dict contains list or Dict -> continue loop for specifierT, valueT in output.items(): if isinstance(valueT, dict) or isinstance(valueT, list): x = True if k ==1:# I have a continues loop so far, thats why break return(output) readL(test)
Basically, I want to have a recursive function that continuesly calls itself until no dict/ list is in the output anymore.
I am also open to any other faster methods on how to read the input.
I am very desperately looking forward for some advice. Please bear with me, i am pretty new to Python.
THANKS A LOT!
UPDATE
I found a partial solution at Flattening Generic JSON List of Dicts or Lists in Python from @poke
def splitObj (obj, prefix = None): ''' Split the object, returning a 3-tuple with the flat object, optionally followed by the key for the subobjects and a list of those subobjects. ''' # copy the object, optionally add the prefix before each key new = obj.copy() if prefix is None else { '{}_{}'.format(prefix, k): v for k, v in obj.items() } # try to find the key holding the subobject or a list of subobjects for k, v in new.items(): # list of subobjects if isinstance(v, list): del new[k] return new, k, v # or just one subobject elif isinstance(v, dict): del new[k] return new, k, [v] return new, None, None def flatten (data, prefix = None): ''' Flatten the data, optionally with each key prefixed. ''' # iterate all items for item in data: # split the object flat, key, subs = splitObj(item, prefix) # just return fully flat objects if key is None: yield flat continue # otherwise recursively flatten the subobjects for sub in flatten(subs, key): sub.update(flat) yield sub
But as my input has changed as well a bit:
input = [{'states': ['USED'], 'niceName': '1-series', 'id': 'BMW_1_Series', 'years': [{'styles': [{'trim': '128i', 'states': ['USED'], 'submodel': {'body': 'Convertible', 'niceName': 'convertible', 'modelName': '1 Series Convertible'}, 'name': '128i 2dr Convertible (3.0L 6cyl 6M)', 'id': 100994560}, {'trim': '128i', 'states': ['USED'], 'submodel': {'body': 'Coupe', 'niceName': 'coupe', 'modelName': '1 Series Coupe'}, 'name': '128i 2dr Coupe (3.0L 6cyl 6M)', 'id': 100974974}, {'trim': '135i', 'states': ['USED'], 'submodel': {'body': 'Coupe', 'niceName': 'coupe', 'modelName': '1 Series Coupe'}, 'name': '135i 2dr Coupe (3.0L 6cyl Turbo 6M)', 'id': 100974975}, {'trim': '135i', 'states': ['USED'], 'submodel': {'body': 'Convertible', 'niceName': 'convertible', 'modelName': '1 Series Convertible'}, 'name': '135i 2dr Convertible (3.0L 6cyl Turbo 6M)', 'id': 100994561} ], 'states': ['USED'], 'id': 100524709, 'year': 2008}, {'styles': [{'trim': '135i', 'states': ['USED'], 'submodel': {'body': 'Coupe', 'niceName': 'coupe', 'modelName': '1 Series Coupe'}, 'name': '135i 2dr Coupe (3.0L 6cyl Turbo 6M)', 'id': 101082656}, {'trim': '128i', 'states': ['USED'], 'submodel': {'body': 'Coupe', 'niceName': 'coupe', 'modelName': '1 Series Coupe'}, 'name': '128i 2dr Coupe (3.0L 6cyl 6M)', 'id': 101082655}, {'trim': '135i', 'states': ['USED'], 'submodel': {'body': 'Convertible', 'niceName': 'convertible', 'modelName': '1 Series Convertible'}, 'name': '135i 2dr Convertible (3.0L 6cyl Turbo 6M)', 'id': 101082663}, {'trim': '128i', 'states': ['USED'], 'submodel': {'body': 'Convertible', 'niceName': 'convertible', 'modelName': '1 Series Convertible'}, 'name': '128i 2dr Convertible (3.0L 6cyl 6M)', 'id': 101082662} ], 'states': ['USED'], 'id': 100503222, 'year': 2009}, {'styles': [{'trim': '128i', 'states': ['USED'], 'submodel': {'body': 'Coupe', 'niceName': 'coupe', 'modelName': '1 Series Coupe'}, 'name': '128i 2dr Coupe (3.0L 6cyl 6M)', 'id': 101200599}, {'trim': '135i', 'states': ['USED'], 'submodel': {'body': 'Coupe', 'niceName': 'coupe', 'modelName': '1 Series Coupe'}, 'name': '135i 2dr Coupe (3.0L 6cyl Turbo 6M)', 'id': 101200600}, {'trim': '135i', 'states': ['USED'], 'submodel': {'body': 'Convertible', 'niceName': 'convertible', 'modelName': '1 Series Convertible'}, 'name': '135i 2dr Convertible (3.0L 6cyl Turbo 6M)', 'id': 101200607}, {'trim': '128i', 'states': ['USED'], 'submodel': {'body': 'Convertible', 'niceName': 'convertible', 'modelName': '1 Series Convertible'}, 'name': '128i 2dr Convertible (3.0L 6cyl 6M)', 'id': 101200601} ], 'states': ['USED'], 'id': 100529091, 'year': 2010}, {'styles': [{'trim': '128i', 'states': ['USED'], 'submodel': {'body': 'Coupe', 'niceName': 'coupe', 'modelName': '1 Series Coupe'}, 'name': '128i 2dr Coupe (3.0L 6cyl 6M)', 'id': 101288165}, {'trim': '135i', 'states': ['USED'], 'submodel': {'body': 'Coupe', 'niceName': 'coupe', 'modelName': '1 Series Coupe'}, 'name': '135i 2dr Coupe (3.0L 6cyl Turbo 6M)', 'id': 101288166}, {'trim': '135i', 'states': ['USED'], 'submodel': {'body': 'Convertible', 'niceName': 'convertible', 'modelName': '1 Series Convertible'}, 'name': '135i 2dr Convertible (3.0L 6cyl Turbo 6M)', 'id': 101288298}, {'trim': '128i', 'states': ['USED'], 'submodel': {'body': 'Convertible', 'niceName': 'convertible', 'modelName': '1 Series Convertible'}, 'name': '128i 2dr Convertible (3.0L 6cyl 6M)', 'id': 101288297} ], 'states': ['USED'], 'id': 100531309, 'year': 2011}, {'styles': [{'trim': '128i', 'states': ['USED'], 'submodel': {'body': 'Convertible', 'niceName': 'convertible', 'modelName': '1 Series Convertible'}, 'name': '128i 2dr Convertible (3.0L 6cyl 6M)', 'id': 101381667}, {'trim': '135i', 'states': ['USED'], 'submodel': {'body': 'Convertible', 'niceName': 'convertible', 'modelName': '1 Series Convertible'}, 'name': '135i 2dr Convertible (3.0L 6cyl Turbo 6M)', 'id': 101381668}, {'trim': '128i', 'states': ['USED'], 'submodel': {'body': 'Coupe', 'niceName': 'coupe', 'modelName': '1 Series Coupe'}, 'name': '128i 2dr Coupe (3.0L 6cyl 6M)', 'id': 101381665}, {'trim': '135i', 'states': ['USED'], 'submodel': {'body': 'Coupe', 'niceName': 'coupe', 'modelName': '1 Series Coupe'}, 'name': '135i 2dr Coupe (3.0L 6cyl Turbo 6M)', 'id': 101381666} ], 'states': ['USED'], 'id': 100534729, 'year': 2012}, {'styles': [{'trim': '128i', 'states': ['USED'], 'submodel': {'body': 'Coupe', 'niceName': 'coupe', 'modelName': '1 Series Coupe'}, 'name': '128i 2dr Coupe (3.0L 6cyl 6M)', 'id': 200428722}, {'trim': '128i', 'states': ['USED'], 'submodel': {'body': 'Convertible', 'niceName': 'convertible', 'modelName': '1 Series Convertible'}, 'name': '128i 2dr Convertible (3.0L 6cyl 6M)', 'id': 200428721}, {'trim': '135is', 'states': ['USED'], 'submodel': {'body': 'Coupe', 'niceName': 'coupe', 'modelName': '1 Series Coupe'}, 'name': '135is 2dr Coupe (3.0L 6cyl Turbo 6M)', 'id': 200421701}, {'trim': '135i', 'states': ['USED'], 'submodel': {'body': 'Coupe', 'niceName': 'coupe', 'modelName': '1 Series Coupe'}, 'name': '135i 2dr Coupe (3.0L 6cyl Turbo 6M)', 'id': 200428724}, {'trim': '135i', 'states': ['USED'], 'submodel': {'body': 'Convertible', 'niceName': 'convertible', 'modelName': '1 Series Convertible'}, 'name': '135i 2dr Convertible (3.0L 6cyl Turbo 6M)', 'id': 200428723}, {'trim': '128i SULEV', 'states': ['USED'], 'submodel': {'body': 'Coupe', 'niceName': 'coupe', 'modelName': '1 Series Coupe'}, 'name': '128i SULEV 2dr Coupe (3.0L 6cyl 6M)', 'id': 200428726}, {'trim': '128i SULEV', 'states': ['USED'], 'submodel': {'body': 'Convertible', 'niceName': 'convertible', 'modelName': '1 Series Convertible'}, 'name': '128i SULEV 2dr Convertible (3.0L 6cyl 6M)', 'id': 200428725}, {'trim': '135is', 'states': ['USED'], 'submodel': {'body': 'Convertible', 'niceName': 'convertible', 'modelName': '1 Series Convertible'}, 'name': '135is 2dr Convertible (3.0L 6cyl Turbo 6M)', 'id': 200428727} ], 'states': ['USED'], 'id': 200421700, 'year': 2013} ], 'name': '1 Series', 'make': {'niceName': 'bmw', 'name': 'BMW', 'id': 200000081} }]
But I receive the error:
AttributeError: 'str' object has no attribute 'update'
as it is not handling
'states': ['USED']
i thinkWhat can I do about it?
I moved this problem to Flatten nested JSON (Dict, List) into List to prepare to write into DB Please comment there. Thanks!
解决方案If I understand you correctly, you are trying to flatten your JSON, but you only want to flatten it when you encounter a certain key or keys. If that's the case you can try this:
Given:
from pprint import pprint input_list = [{"id":"BMW_1_Series", "years":[{"id":10052,"year":2008, "styles":[{"id":560,"name":"128i 2", "submodel":{"body":"Conver","niceName":"conve"},"trim":"128i"}, {"id":561,"name":"135i ", "submodel":{"body":"Conver","niceName":"conver"},"trim":"135i"} ] }, {"id":427,"year":2016, "styles":[{"id":433,"name":"228i ", "submodel":{"body":"Conve", "niceName":"conver"},"trim":"228i SULEV"}, {"id":431,"name":"M235i", "submodel":{"body":"Coupe", "niceName":"m235i"},"trim":"M235i"} ] } ] } #I deleted the other entries, but it is a list ]
Use the functions:
def flatten(something,parent_key=None): if parent_key==None: prefix = "" else: prefix = parent_key+"_" if type(something) == type({}): temp={} for key in something: temp.update(flatten(something[key],prefix+key)) return temp elif type(something) == type([]): temp = {} for index in range(len(something)): temp.update(flatten(something[index],prefix+str(index))) # temp.update(flatten(something[index],prefix+str(something[index]['id']))) return temp else: return {parent_key:something} def sometimes_flatten(something, flatten_keys): if type(something) == type({}): temp={} for key in something: if key in flatten_keys: temp.update(flatten(something[key],key)) else: temp.update({key:sometimes_flatten(something[key],flatten_keys)}) return temp elif type(something) == type([]): return [sometimes_flatten(x,flatten_keys) for x in something] else: return something
then call them here:
if __name__=='__main__': flatten_keys = ['years'] a = sometimes_flatten(input_list,flatten_keys) pprint(a)
but you can put any of the keys into the
flatten_keys
variable to change how it behaves and how much flattening it will do这篇关于Python:将嵌套JSON写入列表中的多个元素的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!