Python 将嵌套元组列表转换为字典
Python convert a list of nested tuples into a dict
好的,所以我正在尝试编写一个 Python 函数,将此处的第一行(嵌套元组列表)转换为第二行,一个扁平化的字典:
[('Ka',0.6), ('La', 0.6), (('Ma', 0.7), ('Na', 0.8), ('Oa', 0.9))]
{'La': 0.6, 'Ma': 0.7, 'Ka': 0.6, 'Na': 0.8, 'Oa': 0.9}
有点复杂的是列表中的外部元组是不同对象的成员,函数的参数是这些对象的列表。希望下面的代码解释了这一点。
现在我实际上已经设法拼凑出这个问题的解决方案,但它太可怕了,我不得不问如何以更 pythonic / 更少混淆的方式做到这一点:
def theFunction(args):
# Please don't ask me how this works. It just does.
flatten = lambda *n: (e for a in n for e in (flatten(*a) if
isinstance(a, (tuple, list)) else (a,)))
return dict(list(zip(*([iter(list(flatten(list(l.sn for l in args))))]*2))))
class le:
def __init__(self,n):
self.sn = (n,0.6)
class lf:
def __init__(self,n,m,o):
self.sn = (n,0.7), (m,0.8), (o, 0.9)
l1 = le("Ka")
l2 = le("La")
l3 = lf("Ma","Na","Oa")
theList = [l1,l2,l3]
print([l.sn for l in theList])
print(theFunction(theList))
两个打印语句将问题顶部的两行作为输出。
您能否更改 le
的定义,使 self.sn
成为元组的元组,就像 lf
中那样?如果是这样,这很容易:
class le:
def __init__(self, n):
self.sn = (n, 0.6),
# ^ make self.sn a tuple of tuples in all cases
class lf:
def __init__(self, n, m, o):
self.sn = (n, 0.7), (m, 0.8), (o, 0.9)
l1 = le("Ka")
l2 = le("La")
l3 = lf("Ma","Na","Oa")
theList = [l1, l2, l3]
result = dict([tup for thing in theList for tup in thing.sn])
# result == {'Na': 0.8, 'Ka': 0.6, 'Ma': 0.7, 'Oa': 0.9, 'La': 0.6}
此外,也许考虑不要在短变量名中如此随意地使用小写字母 "L"s,因为在大多数字体中阅读起来很费力。
您可以轻松地编写一个递归展平器,但是对于元组的双元素元组,这不会像预期的那样表现,例如(('tuple','one'), ('tuple','two'))
def recurse_flatten(seq):
for el in seq:
if isinstance(el, tuple) and len(el)==2:
yield el
else:
yield from recurse_flatten(el)
>>> dict(recurse_flatten([('Ka',0.6), ('La', 0.6), (('Ma', 0.7), ('Na', 0.8), ('Oa', 0.9))]))
{'Ma': 0.7, 'Na': 0.8, 'La': 0.6, 'Ka': 0.6, 'Oa': 0.9}
您可以通过改进您的 yield
条件来取得更大的成功:
def recurse_flatten(seq):
for el in seq:
if isinstance(el, tuple) and len(el)==2:
one,two = el
if isinstance(one, str) and isinstance(two,float):
yield el
continue
yield from recurse_flatten(el)
好的,所以我正在尝试编写一个 Python 函数,将此处的第一行(嵌套元组列表)转换为第二行,一个扁平化的字典:
[('Ka',0.6), ('La', 0.6), (('Ma', 0.7), ('Na', 0.8), ('Oa', 0.9))]
{'La': 0.6, 'Ma': 0.7, 'Ka': 0.6, 'Na': 0.8, 'Oa': 0.9}
有点复杂的是列表中的外部元组是不同对象的成员,函数的参数是这些对象的列表。希望下面的代码解释了这一点。
现在我实际上已经设法拼凑出这个问题的解决方案,但它太可怕了,我不得不问如何以更 pythonic / 更少混淆的方式做到这一点:
def theFunction(args):
# Please don't ask me how this works. It just does.
flatten = lambda *n: (e for a in n for e in (flatten(*a) if
isinstance(a, (tuple, list)) else (a,)))
return dict(list(zip(*([iter(list(flatten(list(l.sn for l in args))))]*2))))
class le:
def __init__(self,n):
self.sn = (n,0.6)
class lf:
def __init__(self,n,m,o):
self.sn = (n,0.7), (m,0.8), (o, 0.9)
l1 = le("Ka")
l2 = le("La")
l3 = lf("Ma","Na","Oa")
theList = [l1,l2,l3]
print([l.sn for l in theList])
print(theFunction(theList))
两个打印语句将问题顶部的两行作为输出。
您能否更改 le
的定义,使 self.sn
成为元组的元组,就像 lf
中那样?如果是这样,这很容易:
class le:
def __init__(self, n):
self.sn = (n, 0.6),
# ^ make self.sn a tuple of tuples in all cases
class lf:
def __init__(self, n, m, o):
self.sn = (n, 0.7), (m, 0.8), (o, 0.9)
l1 = le("Ka")
l2 = le("La")
l3 = lf("Ma","Na","Oa")
theList = [l1, l2, l3]
result = dict([tup for thing in theList for tup in thing.sn])
# result == {'Na': 0.8, 'Ka': 0.6, 'Ma': 0.7, 'Oa': 0.9, 'La': 0.6}
此外,也许考虑不要在短变量名中如此随意地使用小写字母 "L"s,因为在大多数字体中阅读起来很费力。
您可以轻松地编写一个递归展平器,但是对于元组的双元素元组,这不会像预期的那样表现,例如(('tuple','one'), ('tuple','two'))
def recurse_flatten(seq):
for el in seq:
if isinstance(el, tuple) and len(el)==2:
yield el
else:
yield from recurse_flatten(el)
>>> dict(recurse_flatten([('Ka',0.6), ('La', 0.6), (('Ma', 0.7), ('Na', 0.8), ('Oa', 0.9))]))
{'Ma': 0.7, 'Na': 0.8, 'La': 0.6, 'Ka': 0.6, 'Oa': 0.9}
您可以通过改进您的 yield
条件来取得更大的成功:
def recurse_flatten(seq):
for el in seq:
if isinstance(el, tuple) and len(el)==2:
one,two = el
if isinstance(one, str) and isinstance(two,float):
yield el
continue
yield from recurse_flatten(el)