我有一个列表元组(元组等)的嵌套列表,如下所示:
[(' person',
[(('surname', u'Doe', True),),
(('name', u'John', False),),
('contact',
[(('email', u'john@doe.me', True),),
(('phone', u'+0123456789', False),),
(('fax', u'+0987654321', False),)]),
('connection',
[(('company', u'ibcn', True),),
('contact',
[(('email', u'mail@ibcn.com', True),),
(('address', u'main street 0', False),),
(('city', u'pythonville', False),),
(('fax', u'+0987654321', False),)])])])]
无法知道列表中的(双)元组数量以及嵌套的深度。
我想将它转换为嵌套字典(字典),消除布尔值,如下所示:
{'person': {'name': 'John', 'surname': 'Doe',
'contact': {'phone': '+0123456789', 'email': 'john@doe.me','fax': '+0987654321',
'connection': {'company name': 'ibcn', 'contact':{'phone': '+2345678901',
'email': 'mail@ibcn.com', 'address': 'main street 0'
'city': 'pythonville', 'fax': +0987654321'
}}}}}
到目前为止,我所拥有的是一种递归方法,可以按行方式打印嵌套结构:
def tuple2dict(_tuple):
for item in _tuple:
if type(item) == StringType or type(item) == UnicodeType:
print item
elif type(item) == BooleanType:
pass
else:
tuple2dict(item)
但是,我不确定我是否走在正确的轨道上......
编辑: 我编辑了原始结构,因为它缺少逗号。
答案 0 :(得分:3)
你走在正确的轨道上。递归方法将起作用。据我可以从您的示例数据中看出,每个元组 first 都包含字符串项,包含密钥。之后你有另一个元组或列表作为值,或者一个字符串值后跟一个布尔值true或false。
修改强>
递归的技巧是你必须知道何时停止。基本上,在你的情况下,最深的结构似乎是嵌套的三个元组,将名称与值匹配。
黑客攻击。我可耻地承认这是世界上最丑陋的代码。
def tuple2dict(data):
d = {}
for item in data:
if len(item) == 1 and isinstance(item, tuple):
# remove the nested structure, you may need a loop here
item = item[0]
key = item[0]
value = item[1]
d[key] = value
continue
key = item[0]
value = item[1]
if hasattr(value, '__getitem__'):
value = tuple2dict(value)
d[key] = value
return d
答案 1 :(得分:1)
不漂亮......但它有效...基本上
def t2d(t):
if isinstance(t,basestring):return t
length = len(t)
if length == 1:
return t2d(t[0])
if length == 2:
t1,t2 = t2d(t[0]),t2d(t[1])
print "T:",t1,t2
if isinstance(t1,dict) and len(t1) == 1:
t2['name'] = t1.values()[0]
t1 = t1.keys()[0]
return dict([[t1,t2]])
if length == 3 and isinstance(t[2],bool):
return t2d(t[:2])
L1 =[t2d(tp) for tp in t]
L2 = [lx.items() for lx in L1]
L3 = dict( [i[0] for i in L2])
return L3
我应该提到它特别适用于您发布的字典...(似乎公司设置得不对,所以我入侵了它(参见t2 ['name'] ...))
答案 2 :(得分:0)
你肯定是在正确的轨道上。递归函数是可行的方法。
字典可以从可迭代给出长度为2的元组构建。 现在,为了摆脱布尔值,你可以使用切片。只需切掉除前两个元素之外的所有内容。
>> (1,2,3)[:3]
(1,2)
答案 3 :(得分:0)
这是我的最终解决方案。我必须承认,不是很优雅。 它还通过将密钥与现有密钥连接来处理密钥的多个条目。
def tuple2dict(_obj):
_dict = {}
for item in _obj:
if isinstance(item, tuple) or isinstance(item, list):
if isinstance(item[0], basestring):
_dict[item[0]] = tuple2dict(item[1])
else:
if isinstance(item[0], tuple):
# if the key already exists, then concatenate the old
# value with the new one, adding a space in between.
_key = item[0][0]
if _key in _dict:
_dict[_key] = " ".join([_dict[_key], item[0][1]])
else:
_dict[_key] = item[0][1]
return _dict