简体   繁体   中英

How do I sort dictionary values within a list?

I am continuing with a coding exercise which has me return a dictionary where the key is the length of a word and the value is the word itself. This is done by splitting a text, which is the parameter passed to the get_word_len_dict(text) function and counting the number of characters. The length is then sorted and outputted in print_dict_in_key_order(a_dict).

I get an output like this:

2 : ['to', 'is']
3 : ['why', 'you', 'say', 'are', 'but', 'the', 'wet']
4 : ['does', 'when', 'four', 'they', 'have']
5 : ['there', 'stars', 'check', 'paint']
7 : ['someone', 'believe', 'billion']

Which looks right, but what if I wanted to order the values within the list by alphabetical order? That means that words starting in caps should also be prioritised. For example. ['May', 'and'].

Ideally, I would want an output like this with the values in alphabetical order:

2 : ['is', 'to']
3 : ['are', 'but', 'say', 'the', 'wet', 'why', 'you']
4 : ['does', 'four', 'have', 'they', 'when']
5 : ['check', 'paint', 'stars', 'there']
7 : ['believe', 'billion', 'someone']

I have managed to sort the keys so far within the print_dict_in_key_order(a_dict), but not sure how to go about it if I want to also sort the values?

def get_word_len_dict(text):
    dictionary = {}
    word_list = text.split()
    for word in word_list:
        letter = len(word)

        dictionary.setdefault(letter,[])

        if word not in dictionary[letter]:
            dictionary[letter].append(word)

    return dictionary

def test_get_word_len_dict():
    text = 'why does someone believe you when you say there are four billion stars but they have to check when you say the paint is wet'
    the_dict = get_word_len_dict(text)
    print_dict_in_key_order(the_dict)


def print_dict_in_key_order(a_dict): 
    all_keys = list(a_dict.keys()) 
    all_keys.sort() 
    for key in all_keys: 
        print(key, ":", a_dict[key]) 

Given this dict

d = {
    2: ['to', 'is'],
    3: ['why', 'you', 'say', 'are', 'but', 'the', 'wet'],
    4: ['does', 'when', 'four', 'they', 'have'],
    5: ['there', 'stars', 'check', 'paint'],
    7: ['someone', 'believe', 'billion'],
    }

You can sort the values like this:

{k: sorted(v) for k, v in d.items()}

Output (via pprint ):

{2: ['is', 'to'],
 3: ['are', 'but', 'say', 'the', 'wet', 'why', 'you'],
 4: ['does', 'four', 'have', 'they', 'when'],
 5: ['check', 'paint', 'stars', 'there'],
 7: ['believe', 'billion', 'someone']}

Though if you only care about sorting it when printing, just change this line in your code:

print(key, ":", a_dict[key])

to this:

print(key, ":", sorted(a_dict[key]))

What you want to do is to group by length and then sort by value (since uppercase letters are "smaller" than lowercase letters when compared lexicographically), then remove duplicates from each group and put everything in a dict comprehension.

Note that itertools.groupby , unlike the analogous function in, say, pandas , will treat noncontiguous groups as distinct, so we need to sort by length first.

Example:

from itertools import groupby
from pprint import pprint

def solution(sentence):
    sorted_words = sorted(sentence.split(' '), key=len)
    return {length: sorted(set(words)) for length, words in groupby(sorted_words, len)}

sentence =  'Why does someone believe you when you say there are four billion stars but they have to check when you say the paint is wet'

pprint(solution(sentence))

Output:

{2: ['is', 'to'],
 3: ['Why', 'are', 'but', 'say', 'the', 'wet', 'you'],
 4: ['does', 'four', 'have', 'they', 'when'],
 5: ['check', 'paint', 'stars', 'there'],
 7: ['believe', 'billion', 'someone']}

Notice that 'Why' comes before the others because it starts with a capital letter, and the rest are sorted alphabetically.

If you want to retain your function structure, you can just sort each list in your dictionary inplace:

def get_word_len_dict(text):
    dictionary = {}
    word_list = text.split()
    for word in word_list:
        letter = len(word)

        dictionary.setdefault(letter,[])

        if word not in dictionary[letter]:
            dictionary[letter].append(word)

    for words in dictionary.values():
        words.sort()

    return dictionary
d = {
    2: ['to', 'is'],
    3: ['why', 'you', 'say', 'are', 'but', 'the', 'wet'],
    4: ['does', 'when', 'four', 'they', 'have'],
    5: ['there', 'stars', 'check', 'paint'],
    7: ['someone', 'believe', 'billion'],
    }

for i in d:
    d[i].sort()
print(d)

output

   {
    2: ['is', 'to'],
    3: ['are', 'but', 'say', 'the', 'wet', 'why', 'you'],
    4: ['does', 'four', 'have', 'they', 'when'], 
    5: ['check', 'paint', 'stars', 'there'], 
    7: ['believe', 'billion', 'someone']
    }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM