问题描述
mylist = [(0.8132195134810816,'A'),(0.79314903781799,'B'),(0.3931539216409497,(0.23487952756579994,(0.06686513021322447,'C'),(0.008103227303653366,(0.007403104126575008,'D'),(-0.0041128367759631496,(-0.005739579154553378,(-0.008074572907817046,'B')]
#我已经尝试了一些转换。注意,我可以使用for循环来做到这一点。我想知道是否#可以通过字典理解来做到这一点。当然,我可以建立一个常规的#dictionary,但是希望有一系列过滤器单线。
newdict = dict()
for symbol in ['A','B','C','D']: # semesters
values = [item for item,symbol_item in mylist if symbol_item == symbol]
print (symbol,sum(values)/len(values))
newdict[symbol] = sum(values)/len(values)
#我希望有一种方法可以不列出符号
mydict = defaultdict(list)
mydict.update({key: (mydict[key] + [value]) for value,key in my list})
解决方法
您可以使用itertools.groupby
和statistics.mean
来确保输入是按字母排序的,这里我使用operator.itemgetter
快速获取数字和字母:
from itertools import groupby
from statistics import mean
from operator import itemgetter
mylist = [(0.8132195134810816,'A'),(0.79314903781799,'B'),(0.3931539216409497,(0.23487952756579994,(0.06686513021322447,'C'),(0.008103227303653366,(0.007403104126575008,'D'),(-0.0041128367759631496,(-0.005739579154553378,(-0.008074572907817046,'B')]
get_key = itemgetter(1)
get_value = itemgetter(0)
sorted_list = sorted(mylist,key=get_key)
newdict = {k: mean(map(get_value,g)) for k,g in groupby(sorted_list,get_key)}
print(newdict)
{'A': 0.6031867175610156,'B': 0.33998466415865763,'C': 0.03748417875843892,'D': -0.0008164372679805064}
,
您可以做到这一点,但这总是很丑陋。在Python 3.8+中,您可以使用赋值表达式来赋值:
>>> mylist = [(0.8132195134810816,'B')]
>>> result = {
... symbol : sum((values:= [item for item,symbol_item in mylist if symbol_item == symbol])) / len(values)
... for symbol in ['A','B','C','D']
... }
>>> result
{'A': 0.6031867175610156,'D': -0.0008164372679805064}
但这确实使难以理解的混乱。您不应该努力将代码填充为单行代码,这很糟糕。相反,您应该尝试编写可读,高效且可维护的代码。
理解结构有时会使您的代码更具可读性,这是它们的主要优点,如果不是这种情况,则不应该使用它。
请注意,如果没有赋值表达式,则必须依靠另一个从句来分配给values
:
>>> result = {
... symbol : sum(values) / len(values)
... for symbol in ['A','D']
... for values in ([item for item,symbol_item in mylist if symbol_item == symbol],)
... }
>>> result
{'A': 0.6031867175610156,'D': -0.0008164372679805064}
但实际上,与常规的for循环相比,这没有增加任何清晰度。
您还可以 遍历:
[item for item,symbol_item in mylist if symbol_item == symbol]
两次,一次求和,再一次求出长度,但我什至不会写出这种疯狂。
现在,执行此IMO的最佳方法是使用分组习惯用法,并且代码保持线性时间,甚至不需要提前知道符号:
>>> from collections import defaultdict
>>> result = defaultdict(list)
>>> for value,symbol in mylist:
... result[symbol].append(value)
...
>>> result = {symbol: sum(values)/len(values) for symbol,values in result.items()}
>>> result
{'A': 0.6031867175610156,'D': -0.0008164372679805064}