Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Sorting a dictionary with multiple sized values

I have a dictionary that needs to be sorted. I understand that a dictionary cannot be sorted, so I am building a list to perform a sort based upon the index. The problem I am having is that there are duplicate values across multiple keys; also, the values can be multiple lists.

Dictionary:

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'],
}

I need to be able to sort this by key(the number), the color, and the restaurant. The problem I am having is that printing has to be grouped when there are duplicates and I cannot figure out how to sort the list I generate properly.

Example of print by number:

1:
    Red, McDonald's

2:
    Orange, Wendy's
    Purple, Cookout

3:
    Yellow, Longhorn

...

Example of print by color:

Aqua:
    Firehouse Subs, 9

Blue:
    Chipotle, 5

Dark Orange:
    Wendy's, 8

...

My solution to this is to create a list with each of the keys and values in a list. I am still new, and I think this is not the correct way to iterate this dictionary, but it works for the given dictionary.

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]))

Because some values are multiple lists, the if/else statement determines if the value is one or two lists. This then will correctly produce a list of (number, color, restaurant) or (number, color, restaurant, color, restaurant) that can then sort the list by the number. The problem is when I attempt to sort by color or restaurant. I know that I can make the list be only three elements to make the sorting work properly, but when I go to print, I will end up with multiple 2's and 7's. The same result is with restaurant. Also, that does not solve the problem of multiple restaurants. I have searched and tested for about five days attempting different ways to unpack the dictionary, but this is the closest I have got to solving this problem. Any help is appreciated. Thanks in advance.

For clarity, here is the print iteration for numbers:

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]))
like image 298
iamMikeCenters Avatar asked Jun 22 '18 03:06

iamMikeCenters


1 Answers

First step is to convert the dict into a list and homogenize the dict value in the form of array of tuple. Then using the groupBy function from itertools module you can group by the selected param.

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)

Working REPL

like image 145
Vanojx1 Avatar answered Oct 22 '22 18:10

Vanojx1