Python 从排序列表创建字典

Python 从排序列表创建字典,python,python-3.x,dictionary,dictionary-comprehension,Python,Python 3.x,Dictionary,Dictionary Comprehension,这个问题是关于嵌套字典理解的,在问这个问题之前,我已经参考了和。 我有一个列表,它的第一个元素是None,其余元素是一个排序的正数列表 sorted_ar = [None, 10, 10, 12, 12, 12, 15, 25] 我的要求是建立一个字典: key_dict = {10: [3, 2], 12: [12, 3], 15: [6, 1], 25: [7, 1]} 字典的值是一个由两个元素组成的列表,第一个元素是关键字出现次数的索引总和,第二个元素是出现次数。 例如,对于元素12

这个问题是关于嵌套字典理解的,在问这个问题之前,我已经参考了和。
我有一个列表,它的第一个元素是None,其余元素是一个排序的正数列表

sorted_ar = [None, 10, 10, 12, 12, 12, 15, 25] 
我的要求是建立一个字典:

key_dict = {10: [3, 2], 12: [12, 3], 15: [6, 1], 25: [7, 1]}
字典的值是一个由两个元素组成的列表,第一个元素是关键字出现次数的索引总和,第二个元素是出现次数。
例如,对于元素12, 索引之和=3+4+5=12,出现次数为3。
下面的代码可以实现这一点

 key_dict = {k:[0,0] for k in sorted_ar if k!=None}
        for i in range(len(sorted_ar)):
            if sorted_ar[i]:
                key_dict[sorted_ar[i]][0] += i
                key_dict[sorted_ar[i]][1] += 1  
我的要求是使用字典理解准备关键字典

def my_summer(i,num,key_dict):
    key_dict[num][0] = key_dict[num][0]+i
    return key_dict[num][0]  


def my_counter(num,key_dict):
    key_dict[num][1] +=1
    return key_dict[num][1]

sorted_ar = [None, 10, 10, 12, 12, 12, 15, 25] 
key_dict = {k:[0,0] for k in sorted_ar if k!=None}

key_dict = {sorted_ar[i]:[my_summer(i,sorted_ar[i],key_dict),my_counter(sorted_ar[i],key_dict)] for i in range(1,len(sorted_ar))}
我的尝试:

key_dict = { 
    sorted_ar[i]:[ key_dict[sorted_ar[i]][0] + i,key_dict[sorted_ar[i]][0] + 1] 
    for i in range(1,len(sorted_ar)) if sorted_ar[i]!=None
}
但这也带来了一些错误的结果

key_dict = {10: [2, 1], 12: [5, 1], 15: [6, 1], 25: [7, 1]} 
在这种情况下,我应该如何编写词典理解?

您可以尝试以下方法:

sorted_ar = [None, 10, 10, 12, 12, 12, 15, 25] 
new_data = {i:[sum(c for c, b in enumerate(sorted_ar) if b == i), sorted_ar.count(i)] for i in sorted_ar if i}
输出:

{25: [7, 1], 10: [3, 2], 12: [12, 3], 15: [6, 1]}

如果要使用排序,请查看并添加索引:

from itertools import groupby

filtered = ((i, v) for i, v in enumerate(sorted_ar) if v)
grouped = ((v, list(g)) for v, g in groupby(filtered, lambda iv: iv[1]))
result = {v: [sum(i for i, v in g), len(g)] for v, g in grouped}
如果您愿意,您可以将这些内容放在一个表达式中:

result = {v: [sum(i for i, v in g), len(g)] for v, g in (
    (v, list(g)) for v, g in groupby((
        (i, v) for i, v in enumerate(sorted_ar) if v), lambda iv: iv[1]))}
演示:

或者作为一个长句:

>>> {v: [sum(i for i, v in g), len(g)] for v, g in ((v, list(g)) for v, g in groupby(((i, v) for i, v in enumerate(sorted_ar) if v), lambda iv: iv[1]))}
{10: [3, 2], 12: [12, 3], 15: [6, 1], 25: [7, 1]}

另一方面,您的字典方法不需要对输入进行排序,因此可以在O(N)时间内运行(排序需要O(NlogN)时间)。

好的,我已经找到了实现我的行为的方法,不知道为什么,但诀窍是字典更新需要在理解之外进行

def my_summer(i,num,key_dict):
    key_dict[num][0] = key_dict[num][0]+i
    return key_dict[num][0]  


def my_counter(num,key_dict):
    key_dict[num][1] +=1
    return key_dict[num][1]

sorted_ar = [None, 10, 10, 12, 12, 12, 15, 25] 
key_dict = {k:[0,0] for k in sorted_ar if k!=None}

key_dict = {sorted_ar[i]:[my_summer(i,sorted_ar[i],key_dict),my_counter(sorted_ar[i],key_dict)] for i in range(1,len(sorted_ar))}

输出:
{10:[3,2],12:[12,3],15:[6,1],25:[7,1]}

您可以尝试以下方法:

sorted_ar = [None,10, 10, 12, 12, 12, 15, 25]

track={}
for i,j in enumerate(sorted_ar):
    if j not in track:
        track[j]=[(i,1)]
    else:
        track[j].append((i,1))


final_={}
for i,j in track.items():
    if i not in final_:
        final_[i]=(sum(list(map(lambda x:x[0],j))),sum(list(map(lambda x:x[1],j))))

print(final_)
输出:

{None: (0, 1), 10: (3, 2), 15: (6, 1), 12: (12, 3), 25: (7, 1)}

这两种解决方案都是正确的,但是我尝试的方式是有原因的。如果查看有效的for循环代码(第三个代码段),它看起来简单/可读,并且没有比较操作,当找到键时,值会更新。我正在寻找这样一个没有可比性的解决方案,它是用基本python编写的,类似于for循环解决方案。