对具有多个大小值的字典进行排序
Posted
技术标签:
【中文标题】对具有多个大小值的字典进行排序【英文标题】:Sorting a dictionary with multiple sized values 【发布时间】:2018-12-01 11:27:37 【问题描述】:我有一本需要排序的字典。我了解无法对字典进行排序,因此我正在构建一个列表以根据索引执行排序。我遇到的问题是多个键之间存在重复值;此外,值可以是多个列表。
字典:
my_dict =
'1' : ['Red', 'McDonald\'s'],
'2' : [['Orange', 'Wendy\'s'], ['Purple', 'Cookout']],
'3' : ['Yellow', 'Longhorn'],
'4' : ['Green', 'Subway'],
'5' : ['Blue', 'Chipotle'],
'6' : ['Indigo', 'Taco Bell'],
'7' : [['Violet', 'Steak n Shake'], ['Dark Red', 'Five Guys']],
'8' : ['Dark Orange', 'Wendy\'s'],
'9' : ['Aqua', 'Firehouse Subs'],
'10' : ['Magenta', 'McDonald\'s'],
我需要能够按键(数字)、颜色和餐厅对其进行排序。我遇到的问题是,当有重复时必须对打印进行分组,我无法弄清楚如何对我生成的列表进行正确排序。
按数字打印的示例:
1:
Red, McDonald's
2:
Orange, Wendy's
Purple, Cookout
3:
Yellow, Longhorn
...
按颜色打印的示例:
Aqua:
Firehouse Subs, 9
Blue:
Chipotle, 5
Dark Orange:
Wendy's, 8
...
我对此的解决方案是创建一个列表,其中包含列表中的每个键和值。我还是新手,我认为这不是迭代这本字典的正确方法,但它适用于给定的字典。
sorted_number = []
for key, value in my_dict.items():
if len(value[0][0]) > 1:
working_list = (key, value[0][0], value[0][1], value[1][0], value[1][1])
sorted_number.append(working_list)
else:
working_list = (key, value[0], value[1])
sorted_number.append(working_list)
sorted_years = sorted(sorted_years, key=lambda y: y[0][0])
for i in sorted_years:
print(':'.format(i[0]))
if len(i) > 3:
print('\t, '.format(i[1], i[2])
print('\t, '.format(i[3], i[4]))
else:
print('\t, '.format(i[1], i[2]))
由于某些值是多个列表,if/else 语句确定该值是一个还是两个列表。然后,这将正确生成(数字、颜色、餐厅)或(数字、颜色、餐厅、颜色、餐厅)的列表,然后可以按数字对列表进行排序。问题是当我尝试按颜色或餐厅排序时。我知道我可以让列表只有三个元素以使排序正常工作,但是当我去打印时,我最终会得到多个 2 和 7。餐厅的结果相同。此外,这并不能解决多个餐厅的问题。我已经搜索和测试了大约五天,尝试不同的方法来解压字典,但这是我最接近解决这个问题的方法。任何帮助表示赞赏。提前致谢。
为清楚起见,这里是数字的打印迭代:
for i in sorted_number:
print(':'.format(i[0]))
if len(i) > 3:
print('\t, '.format(i[1], i[2]))
print('\t, '.format(i[3], i[4]))
else:
print('\t, '.format(i[1], i[2]))
【问题讨论】:
你读过这个python.org/dev/peps/pep-0265 @NitishKumar 值可以是一个或两个列表。除非我忽略了某些东西,否则解决方案是将字典转换为包含三个元素的列表,然后执行排序。 也许你可以使用 JSON'7' : [['Violet', 'Steak n Shake'], ['Dark Red', 'Five Guys']]
按颜色排序时,您希望如何放置?它应该在'8' : ['Dark Orange', 'Wendy\'s']
(使用'Dark Red'
)之后还是'1' : ['Red', 'McDonald\'s']
(使用'Violet'
)之后?
@SergeBallesta 确实不用担心放置问题,只要在迭代列表或元组时,就可以按照描述打印信息。我的想法是制作一个像(5,Blue,Chipotle)这样的列表,但问题是当你去打印时,你会在 sortby 上有重复(例如 2 McDonald's)。在排序的重复条目上,您应该像这样打印:McDonald's: Red, 1 Magenta, 10 我无法正确格式化评论以显示正确的缩进。
【参考方案1】:
第一步是将dict转为list,将dict值以tuple数组的形式进行同质化。然后使用 itertools 模块中的groupBy 函数,您可以按所选参数进行分组。
class RestourantSorter:
def __init__(self, source):
self._rList = []
""" Dict to list [(key, color, restourant name), ....] """
for key, value in source.items():
for color, rest in value if isinstance(value[0], list) else [value]:
self._rList.append((key,color,rest))
def _byIndex(self, x):
return int(x[0])
def _byColor(self, x):
return x[1]
def _byName(self, x):
return x[2]
def sort(self, sortFn):
""" Sorted data [(key, [... values ...]), ....] """
groups = []
data = sorted(self._rList, key=sortFn)
for k, g in groupby(data, sortFn):
groups.append((k, list(g)))
return groups
def sortByIndex(self):
return self.sort(self._byIndex)
def sortByColor(self):
return self.sort(self._byColor)
def sortByName(self):
return self.sort(self._byName)
工作REPL
【讨论】:
你这个人真了不起!我仍然是一名学生,到目前为止,课堂上的任何内容都没有触及 init 和 self 来建立一个班级。我们轻轻地谈到了班级建设的话题,老实说,我可能总共定义了一两次。这是我的第一堂编程课,我肯定需要进一步研究课堂建设;如果这甚至是正确的术语。我了解这门课中大约 90% 的情况;但是,我需要研究 self 和 init 才能完全掌握一切。再次感谢您!【参考方案2】:当您希望更改或应用不同的索引时,字典并不理想。它只能有一把钥匙。如果您使用数字作为键,则很难切换到按颜色索引。这不是字典的优化目标。
您可以使用自定义类,但我更喜欢使用为处理数据而设计的第 3 方库。这是 Pandas 的示例。
import pandas as pd
from itertools import chain
chainer = chain.from_iterable
# calculate numeric keys including repeats, flat list
keys = list(chainer([k]*(len(v) if isinstance(v[0], list) else 1) \
for k, v in my_dict.items()))
# calculate color-name combinations, list of lists, each sublist of length 2
vals = list(chainer((v if isinstance(v[0], list) else [v] \
for v in my_dict.values())))
# create dataframe
df = pd.DataFrame(vals, columns=['color', 'name'], index=keys)
然后,您可以按数字键、颜色等对所需的输出进行分组,SO 上有许多可用的解决方案。可以进行排序,输出到dict
或使用print
进行迭代。
print(df)
color name
1 Red McDonald's
2 Orange Wendy's
2 Purple Cookout
3 Yellow Longhorn
4 Green Subway
5 Blue Chipotle
6 Indigo Taco Bell
7 Violet Steak n Shake
7 Dark Red Five Guys
8 Dark Orange Wendy's
9 Aqua Firehouse Subs
10 Magenta McDonald's
【讨论】:
以上是关于对具有多个大小值的字典进行排序的主要内容,如果未能解决你的问题,请参考以下文章
python 小技巧, 如何根据字典中的值的大小,对字典中的项排序