Python Forum
Swap key and value of a dictionary - and sort it
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Swap key and value of a dictionary - and sort it
#1
Hello,

The input is this:

Output:
{'Accurate': ['exact', 'precise'], 'exact': ['precise'], 'astute': ['Smart', 'clever'], 'smart': ['clever', 'bright', 'talented']}
And the output is supposed to be this:
Output:
{'precise': ['accurate', 'exact'], 'clever': ['astute', 'smart'], 'talented': ['smart'], 'bright': ['smart'], 'exact': ['accurate'], 'smart': ['astute']}
Note that values of each key are sorted.

My code is this:

def reverse_dictionary(input_dict):

    my_dict= {}

    for key, value in input_dict.items():
        for string in value:
            my_dict.setdefault(string.lower(), []).append(key.lower())
    
    output_dict={k:v for k,v in sorted(my_dict.items(), key=lambda item:item[1])}

    return output_dict
But this code is not producing the expected result. What am I missing here?
Larz60+ write Oct-27-2020, 04:37 PM:
Please post all code, output and errors (it it's entirety) between their respective tags. Refer to BBCode help topic on how to post. Use the "Preview Post" button to make sure the code is presented as you expect before hitting the "Post Reply/Thread" button.

Fixed for you this time, please use bbcode tags on all future posts.
Reply
#2
(Oct-27-2020, 03:24 PM)Omid Wrote: Note that values of each key are sorted.

Perhaps I am missing something, but it appears to me that the values of each key are sorted correctly when I compare the output of your code to the desired output. The only values that can be sorted are those of 'precise' and 'clever', since they are the only keys that have more than one value.

The keys in your returned dictionary are not sorted in the same way as the desired output, but you didn't mention anything about how the keys are to be sorted. For each key in your code's output, the values appear to be the same (and sorted in the same way) as those in the desired output. If I am missing something, please let me know. Think
Reply
#3
What you are missing is what determines the order of the output dictionary. I am missing it too. precise and clever are the first two keys. Is that because they have the most values? But why is talented next?

It took me a while to find a combination of conditions to give me the order precise, clever, talented, bright, exact and smart. I counted letters and computed sums of the ordinal values and looked at sorting based on the values and on particular letters in the values. exact and smart were the most difficult for me.
I got precise, clever, talented, bright, smart and exact fairly early. The sorting key is so bizarre looking that I know there has to be something more direct.
Reply
#4
It was just the wrong index. Use index 0 if you want to sort by keys and if you use 1, you're sorting by values.

If you sort by keys, you should get this order:
In [45]: sorted("precise clever talented bright smart exact".split())
Out[45]: ['bright', 'clever', 'exact', 'precise', 'smart', 'talented']
For example, you can sort your str also by length:
In [46]: sorted("precise clever talented bright smart exact".split(), key=len)
Out[46]: ['smart', 'exact', 'clever', 'bright', 'precise', 'talented']
Now back to your code:
def reverse_dictionary(input_dict):
    my_dict= {}
    for key, value in input_dict.items():
        for string in value:
            my_dict.setdefault(string.lower(), []).append(key.lower())
    output_dict={k:v for k,v in sorted(my_dict.items(), key=lambda item:item[0])} # not index 1, index 0 is the key
    return output_dict


# first iteration
from operator import itemgetter


def reverse_dictionary(input_dict):
    result = {}
    by_key = itemgetter(0)
    for key, values in input_dict.items():
        for string in values:
            result.setdefault(string.lower(), []).append(key.lower())
    return dict(sorted(result.items(), key=by_key))


# second iteration
from collections import defaultdict
from operator import itemgetter


def reverse_dictionary(input_dict):
    result = defaultdict(list)
    by_key = itemgetter(0)
    for key, values in input_dict.items():
        for string in values:
            result[string.lower()].append(key.lower())
    return dict(sorted(result.items(), key=by_key))


# third iteration
from collections import defaultdict
from operator import itemgetter


def sort_dict_keys(mapping):
    return dict(sorted(result.items(), key=itemgetter(0)))


def reverse_dictionary(input_dict):
    result = defaultdict(list)
    for key, values in input_dict.items():
        for string in values:
            result[string.lower()].append(key.lower())
    return sort_dict_keys(result)
If you have a predefined order, you could use a mapping to int.
Predefined order:
def custom_order(key_value, default=0):
    key, _ = key_value
    key_order = {
        "bright": 1,
        "clever": 2,
        "exact": 100,
        "precise": 3,
        "smart": 4,
        "talented": 5,
    }
    return key_order.get(key, default)
It's not the best example because the dict was defined inside the function.
But I hope it helps to clarify that you can do also custom sort order.
Almost dead, but too lazy to die: https://sourceserver.info
All humans together. We don't need politicians!
Reply
#5
Dears,

Thank you so much for taking time to reply my question. It appears that the instructions were confusing and my code was indeed correct.

Regards
Omid
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  Sort a list of dictionaries by the only dictionary key Calab 1 497 Oct-27-2023, 03:03 PM
Last Post: buran
Photo a.sort() == b.sort() all the time 3lnyn0 1 1,327 Apr-19-2022, 06:50 PM
Last Post: Gribouillis
  How to swap two numbers in fields in python Joni_Engr 5 1,873 Jan-11-2022, 09:43 AM
Last Post: menator01
  swap elements in list hshivaraj 3 12,546 Apr-22-2019, 09:23 AM
Last Post: Yoriz
  Sort MULTIDIMENSIONAL Dictionary mirinda 2 4,910 Apr-05-2019, 12:08 PM
Last Post: perfringo
  I am trying to swap two variables with a Function.... Jeff_Waldrop 4 3,104 Mar-04-2019, 10:19 AM
Last Post: Jeff_Waldrop
  yes-no RE pattern swap bluefrog 1 2,666 Jun-08-2018, 07:06 AM
Last Post: volcano63
  Randomise network while maintaining topology of nodes using edge-swap approach Tom1988 3 4,136 May-25-2017, 10:59 PM
Last Post: ichabod801

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020