我有一个list如下
[[['server', ''],['port','8800'],['location','/'],['location','/aa'],['location','bb']],[['server', ''],['port','80'],['location','/'],['location','/aa'],['location','bb']]]
想要得到如下的dict
[{'server': '','port': '8800','location': '/,/aa,/bb'},{'server': '','port': '80','location': '/,/aa,/bb'}]
或者
[{'server': '','port': '8800','location': '/'},{'server': '','port': '8800','location': '/aa'},{'server': '','port': '8800','location': '/bb'},{'server': '','port': '80','location': '/'},{'server': '','port': '80','location': '/aa'},{'server': '','port': '80','location': '/bb'}]
求解
之前有sf上的同学给出了一个例子
def turn2dic(lst):
global key, value
dic = {}
if all([not isinstance(item, list) for item in lst]):
if len(lst) == 2:
key, value = lst
elif len(lst) == 1:
key=lst[0]
value=''
elif len(lst) == 3:
key=lst[0]
value=lst[1]
dic[key] = value
else:
for item in lst:
subdic = turn2dic(item)
print subdic
dic.update(subdic)
print dic
return dic
但是这个上面代码里,location是覆盖的,因为dic.update(subdic),有什么办法是append的?
巴扎黑2017-04-17 17:56:02
def single_turn2dic(lst):
global key, value
dic = {}
if all([not isinstance(item, list) for item in lst]):
if len(lst) == 2:
key, value = lst
elif len(lst) == 1:
key = lst[0]
value = ''
elif len(lst) == 3:
key = lst[0]
value = lst[1]
# dic[key] = value
if value and dic.get(key, ''):
dic[key] += ',' + value
else:
dic[key] = value
else:
for item in lst:
subdic = single_turn2dic(item)
# print subdic
# dic.update(subdic)
for name, name_value in subdic.iteritems():
if name_value and dic.get(name, ''):
dic[name] += ',' + name_value
else:
dic[name] = name_value
# print dic
return dic
servers = [[['server', ''], ['port', '8800'], ['location', '/'], ['location', '/aa'], ['location', 'bb']],
[['server', ''], ['port', '80'], ['location', '/'], ['location', '/aa'], ['location', 'bb']]]
def beautify(servers):
# lst = []
if not isinstance(servers[0][0], list):
return single_turn2dic(servers)
else:
return [beautify(server) for server in servers]
print beautify(servers)
The general idea is [['server', ''], ['port', '8800'], ['location', '/'], ['location', '/aa'], ['location', 'bb']]
This kind of processing is regarded as a unit (the function is modified from the code you gave), and the recursion is to the extent that it can be processed (because the number of layers may not be 2)
PHP中文网2017-04-17 17:56:02
Code:
def turn2dic(lst):
dic = {}
if all([not isinstance(item, list) for item in lst]):
key, value = lst
dic[key] = value
else:
for item in lst:
subdic = turn2dic(item)
for key, value in subdic.items():
dic.setdefault(key, []).append(value)
return dic
results = [turn2dic(item) for item in lst]
print results
Result:
[{'location': ['/', '/aa', 'bb'], 'port': ['8800'], 'server': ['']}, {'location': ['/', '/aa', 'bb'], 'port': ['80'], 'server': ['']}]
I think unnecessary code can be removed. Since the problem this time is relatively simple (since it is determined that the bottom layer is a two-element list this time), there is no need to do too much judgment and processing (even this recursive solution can also be used) Change to a simple method).
I'm not sure if there are any other repetitive things in your information besides location
. I think it's better to process them uniformly, so the values in my dictionary are different from the examples you gave. I use list instead of string. .
伊谢尔伦2017-04-17 17:56:02
Break it apart to look better
from collections import defaultdict
def testtype(t):
return lambda x: isinstance(x, t)
def test(t, lst):
return all(map(t if callable(t) else testtype(t), lst))
def parse_dict(lst):
dct = defaultdict(lambda: [])
for k, v in lst:
dct[k].append(parse(v))
ret = {}
for k, v in dct.items():
if test(str, v):
v = ','.join(v)
elif len(v) == 1:
v = v[0]
ret[k] = v
return ret
def parse(obj):
if not isinstance(obj, list):
return obj
if test(lambda x: len(x) == 2, obj):
return parse_dict(obj)
return list(map(parse, obj))
src= [[['server', ''],['port','8800'],['location','/'],['location','/aa'],['location','bb']],[['server', ''],['port','80'],['location','/'],['location','/aa'],['location','bb']]]
print(parse(src))
ringa_lee2017-04-17 17:56:02
Others have already taught you how to fish, so your level will not improve if you just ask for fish