我正在寻找一种更加pythonic的方法来获取字典列表中每个键的最大值。
我的方法看起来像这样
lst =[{'a':'asdasd', 'b': 123},{'a': 'asdasdasdas'}, {'a':123,'b':'asdasd'}]
dct = {}
for l in lst:
for key in l:
dct.update({key: max(dct.get(key,0), len(str(l.get(key,0))))})
print(dct)
输出结果
{'b':6,'a':11}
需要str函数来获得整数的长度(以及Nones)
这种方法是“pythonic”还是使用列表推导或类似方法更流畅,更易读。
答案 0 :(得分:2)
我认为你的方法是相当Pythonic的,除非我将update
行更改为更清晰:
# A little terse
dct.update({key: max(dct.get(key,0), len(str(l.get(key,0))))})
# A little simpler
dct[key] = max(dct.get(key, 0), len(str(l[key])))
这是一个修改了变量名称的解决方案:
dict_list =[{'a':'asdasd', 'b': 123},{'a': 'asdasdasdas'}, {'a':123,'b':'asdasd'}]
max_lengths = {}
for dictionary in dict_list:
for k, v in dictionary.items():
max_lengths[k] = max(max_lengths.get(k, 0), len(str(v)))
print(max_lengths)
答案 1 :(得分:1)
我之前的回答是错误的,并没有意识到,但这里有两个其他的工作。第一个使用熊猫。它创建一个数据帧,对键进行排序,然后对值进行排序,获取每个组的第一个值,然后创建一个字典
import pandas as pd
lst = [{'a':'asdasd', 'b': 123},{'a': 'asdasdasdas'}, {'a':123,'b':'asdasd'}]
dct={}
d = pd.DataFrame([(k,len(str(v))) for i in lst for k,v in i.items()], columns=['Key','Value'])
d = d.sort(['Key','Value'], ascending=[1,0])
d = d.groupby('Key').first().reset_index()
d = dict(zip(d.Key, d.Value)) #or d.set_index('Key')['Value'].to_dict()
print d
{'a': 11, 'b': 6}
如果你想要一些易于阅读并使用内置模块的东西,那么这应该
lst = [{'a':'asdasd', 'b': 123},{'a': 'asdasdasdas'}, {'a':123,'b':'asdasd'}]
dct={}
for i in lst:
for k,v in i.items():
if k in dct:
if len(str(v)) > dct[k]:
dct[k] = len(str(v))
else:
dct[k] = len(str(v))
print dct
{'a': 11, 'b': 6}
答案 2 :(得分:1)
这是另一种不依赖于排序/压缩的方式,但我不会说一个人比另一个人更像Pythonic。
from itertools import chain
lst =[{'a':'asdasd', 'b': 123}, {'a': 'asdasdasdas'}, {'a':123,'b':'asdasd'}]
dct = {
k: max(len(str(d.get(k, ""))) for d in lst)
for k in set(chain.from_iterable(d.keys() for d in lst))
}
print(dct)
或者,您可以使用groupby:
from itertools import chain, groupby
lst =[{'a':'asdasd', 'b': 123}, {'a': 'asdasdasdas'}, {'a':123,'b':'asdasd'}]
dct = {
k: max(len(str(v)) for _, v in g)
for k, g in groupby(
chain.from_iterable(d.items() for d in lst),
lambda p: p[0]
)
}
print(dct)
答案 3 :(得分:1)
其他答案侧重于使用python功能而不是可读性。我个人认为可读性和简洁性是所有“pythonic”中最重要的。性状。
(我简化为所有内容都使用字符串,但如果你放入str()
那么它也适用于整数)
from collections import defaultdict
lst =[{'a':'asdasd', 'b': '123'},{'b': 'asdasdasdas'}, {'a':'123','b':'asdasd'}]
def merge_dict(dic1,dic2) :
for key,value in dic2.items():
dic1[key].append(value)
combined = defaultdict(list)
for dic in lst:
merge_dict(combined, dic)
print( {key : max(map(len,value)) for key, value in combined.items() } )
答案 4 :(得分:1)
我喜欢这种方式以便于阅读和使用Python:
dicts = [{'a':'asdasd', 'b': 123},{'a': 'asdasdasdas'}, {'a':123,'b':'asdasd'}]
def get_highest(current_highest, items_left):
if not items_left:
return current_highest
else:
item = items_left.pop()
higher = {key: len(str(value)) for key, value in item.items() if (len(str(item[key])) > current_highest.get(key, 0))}
if higher:
current_highest.update(higher)
return get_highest(current_highest, items_left)
print(get_highest(dict(), dicts))
{'b': 6, 'a': 11}