我有一个从数据库中两个字段读取的值字典:字符串字段和数字字段。字符串字段是唯一的,因此它是字典的关键字。
我可以按关键字排序,但如何根据值排序?
注意:我在这里读过堆栈溢出问题。如何根据字典的值对字典列表进行排序?并且可能会更改我的代码,使其具有字典列表,但由于我确实不需要字典列表,我想知道是否有更简单的解决方案来按升序或降序排序。
我有一个从数据库中两个字段读取的值字典:字符串字段和数字字段。字符串字段是唯一的,因此它是字典的关键字。
我可以按关键字排序,但如何根据值排序?
注意:我在这里读过堆栈溢出问题。如何根据字典的值对字典列表进行排序?并且可能会更改我的代码,使其具有字典列表,但由于我确实不需要字典列表,我想知道是否有更简单的解决方案来按升序或降序排序。
当前回答
另一个答案中提到的集合解决方案绝对是极好的,因为您在键和值之间保留了一种联系,这在字典中是极其重要的。
我不同意另一个答案中的第一选择,因为它会扔掉钥匙。
我使用了上面提到的解决方案(代码如下所示),并保留了对键和值的访问权,在我的情况下,排序是对值进行的,但重要的是对值排序后的键排序。
from collections import Counter
x = {'hello':1, 'python':5, 'world':3}
c=Counter(x)
print( c.most_common() )
>> [('python', 5), ('world', 3), ('hello', 1)]
其他回答
字典无法排序,但您可以根据它们构建排序列表。
字典值的排序列表:
sorted(d.values())
按值排序的(键、值)对列表:
from operator import itemgetter
sorted(d.items(), key=itemgetter(1))
我有同样的问题,我这样解决了:
WantedOutput = sorted(MyDict, key=lambda x : MyDict[x])
(回答“不可能对字典进行排序”的人没有读到这个问题!事实上,“我可以对键进行排序,但如何根据值进行排序?”显然意味着他想要一个根据其值排序的键列表。)
请注意,顺序没有很好地定义(具有相同值的键在输出列表中的顺序是任意的)。
正如Dilettant所指出的,Python 3.6现在将保持秩序!我想我应该分享我编写的一个函数,它简化了可迭代(元组、列表、dict)的排序。在后一种情况下,可以对键或值进行排序,并且可以考虑数值比较。仅适用于>=3.6!
当您尝试在包含字符串和int的可迭代对象上使用sorted时,sorted()将失败。当然,您可以使用str()强制字符串比较。然而,在某些情况下,您希望进行实际的数值比较,其中12小于20(字符串比较中不是这种情况)。所以我提出了以下建议。当您需要显式数字比较时,可以使用标志num_as_num,它将尝试通过将所有值转换为浮点数来执行显式数字排序。如果成功,它将进行数字排序,否则将诉诸字符串比较。
欢迎提出改进意见。
def sort_iterable(iterable, sort_on=None, reverse=False, num_as_num=False):
def _sort(i):
# sort by 0 = keys, 1 values, None for lists and tuples
try:
if num_as_num:
if i is None:
_sorted = sorted(iterable, key=lambda v: float(v), reverse=reverse)
else:
_sorted = dict(sorted(iterable.items(), key=lambda v: float(v[i]), reverse=reverse))
else:
raise TypeError
except (TypeError, ValueError):
if i is None:
_sorted = sorted(iterable, key=lambda v: str(v), reverse=reverse)
else:
_sorted = dict(sorted(iterable.items(), key=lambda v: str(v[i]), reverse=reverse))
return _sorted
if isinstance(iterable, list):
sorted_list = _sort(None)
return sorted_list
elif isinstance(iterable, tuple):
sorted_list = tuple(_sort(None))
return sorted_list
elif isinstance(iterable, dict):
if sort_on == 'keys':
sorted_dict = _sort(0)
return sorted_dict
elif sort_on == 'values':
sorted_dict = _sort(1)
return sorted_dict
elif sort_on is not None:
raise ValueError(f"Unexpected value {sort_on} for sort_on. When sorting a dict, use key or values")
else:
raise TypeError(f"Unexpected type {type(iterable)} for iterable. Expected a list, tuple, or dict")
除了使用内置模块等,我尝试手动解决它。。。
首先,我制作了一个函数,其任务是返回dict的每个项的最小值:
def returnminDict(_dct):
dict_items = _dct.items()
list_items = list(dict_items)
init_items = list_items[0]
for i in range(len(list_items)):
if list_items[i][1] > init_items[1]:
continue
else:
init_items = list_items[i]
return init_items
第二,现在我们有一个函数,它返回一个具有最小值的项。然后我做了一个新的格言,并在格言上循环:
def SelectDictSort(_dct):
new_dict = {}
while _dct:
mindict = returnminDict(_dct)
new_dict.update(dict((mindict,)))
_dct.pop(mindict[0])
return new_dict
我尝试使用SelectDictSort({2:5,5:1,4:3,1:1,0:1,9:2,8:2})。它将返回:
{0: 1, 1: 1, 5: 1, 8: 2, 9: 2, 4: 3, 2: 5}
嗯……我不知道哪一个是正确的,但这是我尝试过的。。。
months = {"January": 31, "February": 28, "March": 31, "April": 30, "May": 31,
"June": 30, "July": 31, "August": 31, "September": 30, "October": 31,
"November": 30, "December": 31}
def mykey(t):
""" Customize your sorting logic using this function. The parameter to
this function is a tuple. Comment/uncomment the return statements to test
different logics.
"""
return t[1] # sort by number of days in the month
#return t[1], t[0] # sort by number of days, then by month name
#return len(t[0]) # sort by length of month name
#return t[0][-1] # sort by last character of month name
# Since a dictionary can't be sorted by value, what you can do is to convert
# it into a list of tuples with tuple length 2.
# You can then do custom sorts by passing your own function to sorted().
months_as_list = sorted(months.items(), key=mykey, reverse=False)
for month in months_as_list:
print month