切片字典中的列表

0 投票
2 回答
1607 浏览
提问于 2025-04-17 15:09

我有一个字典,里面存着一些列表,每个列表都有超过50个项目。为了简单起见,假设这个字典的键是['a','b','c']。我花了太多时间想要找到一种非常“Python风格”的方法来对这些列表进行排序和切片。到目前为止,我的代码是:

dict = dictionary_of_lists under discussion
[dict[k].sort(reverse=True) for k in dict.keys()]
for k, l in dict.items():
    slice = 10 if k in ('a','c') else 20
    dict[k] = l[:slice]

这样我得到了一个排序好的、修整过的列表,正是我想要的。但我希望能有一行代码,比如 [dict[k].sort(reverse=True) for k in dict.keys()],这样在对排序后的列表进行切片时就能更方便。如果有人能想出如何把排序和切片结合起来,那他就是我的英雄。

更新:首先,我喜欢问一些稍微复杂的问题,因为这能帮助我提高编程技能(因为我是自学的)。所以谢谢下面的每一个人!这是我新的代码:

for c in list_of_categories:
    list = [getattr(p,c.name) for p in people if hasattr(p,c.name)]
    slice = c.get_slice_value # I added an @property function to a class named `Category`
    c.total = sum(sorted(list, reverse=True)[:slice])

2 个回答

1

sort() 是在原地排序的,也就是说它会直接改变每个列表的内容。如果你想保留原来的列表,最好是创建新的列表:

[sorted(d[k], reverse = True)[:10 if k in ('a','c') else 20] for k in d.keys()]

不过要注意,这样写可能不太容易理解。

1

在编程中,带有副作用的列表推导式通常被认为是不好的写法。建议你创建一个新的字典来代替:

dct = {k: sorted(l, reverse=True)[:10 if k in ('a','c') else 20] 
    for k, l in dct.items()}

另外,现在切片的值看起来有点随意,可能单独配置这些值会更好,比如:

slices = {
    'a': 10,
    'b': 10,
    'c': 20
}    

dct = {k: sorted(l, reverse=True)[:slices[k]] 
    for k, l in dct.items()}

撰写回答