0

I have a main and blank dictionary,

Dairy_goods = {1:{'item':'Milk','price':2.47,'gst':0.16,'offer':'Yes'},
    2:{'item':'Butter','price':4.50,'gst':0.32,'offer':'No',},
    3:{'item':'Egg','price':3.40,'gst':0.24,'offer':'No'}}

I have coded it so that it will sort by alphabetical order.

While True:
    res = sorted(Dairy_goods.items(), key = lambda x: x[1]['item']) #by name
    print("The sorted dictionary by marks is : " + str(res))

the output would be

    The sorted dictionary by marks is : [(2, {'item': 'Butter', 'price': 4.5, 'gst': 0.32, 'offer': 'No'}), 
(3, {'item': 'Egg', 'price': 3.4, 'gst': 0.24, 'offer': 'No'}), 
(1, {'item': 'Milk', 'price': 2.47, 'gst': 0.16, 'offer': 'Yes'})]

As you can see the main key value are messed up after the sort and would like to know if there was a way to change/update the key name so it would be listed in order.

#desired output
    The sorted dictionary by marks is : [(1, {'item': 'Butter', 'price': 4.5, 'gst': 0.32, 'offer': 'No'}), 
(2, {'item': 'Egg', 'price': 3.4, 'gst': 0.24, 'offer': 'No'}), 
(3, {'item': 'Milk', 'price': 2.47, 'gst': 0.16, 'offer': 'Yes'})]

Thank you.

*edit: I realize the title of this post might not fit what I am looking for do let me know how I should title this issue if you know, Thank you

*edit: As AKS has mentioned, using enumerate worked great! but as I would still like the value of the number to be attached to the list, for example when i select option '1' it would still give me the key values of 'Milk' as it is the first key in the main dictionary is there any work around for this?

#output now
[(1, {'item': 'Butter', 'price': 4.5, 'gst': 0.32, 'offer': 'No'}),
 (2, {'item': 'Egg', 'price': 3.4, 'gst': 0.24, 'offer': 'No'}),
 (3, {'item': 'Milk', 'price': 2.47, 'gst': 0.16, 'offer': 'Yes'})]

select your input: 1 #user input
how many do you want?: 1 #user input

Milk , {'Quantity': 1, 'Individual price': 2.47, 'total': 2.47, 'GST': 0.16, 'offer': 'Yes'} #output

3 Answers 3

2
>>> list(enumerate(sorted(Dairy_goods.values(), key=lambda x: x['item']), start=1)) 
[(1, {'item': 'Butter', 'price': 4.5, 'gst': 0.32, 'offer': 'No'}),
 (2, {'item': 'Egg', 'price': 3.4, 'gst': 0.24, 'offer': 'No'}),
 (3, {'item': 'Milk', 'price': 2.47, 'gst': 0.16, 'offer': 'Yes'})]

Just sort on values and use enumerate.

If you don't want a list but a dict, just replace list with dict.


I would still like the value of the number to be attached to the list, for example when i select option '1' it would still give me the key values of 'Milk' as it is the first key in the main dictionary is there any work around for this?

There is no code in the post to show how the values are accessed. But because you are getting Milk, I guess you are still using Dairy_goods to access the value. As I have mentioned in the comment below, you can do two things:

  • Either, assign the value to Dairy_goods and this way you can keep the rest of the code as it is because you can access the first element using Dairy_goods[1] etc.
Dairy_goods = dict(enumerate(sorted(Dairy_goods.values(), key=lambda x: x['item']), start=1))
  • Or, assign this sorted dict to a new value and use new_dairy_goods to access the value going forward.
new_dairy_goods = dict(enumerate(sorted(Dairy_goods.values(), key=lambda x: x['item']), start=1))
Sign up to request clarification or add additional context in comments.

6 Comments

Ah thank you! this worked and got the display as I want to but when I keyed in, option 1 'Butter' It would still give me the 'Milk' Option, is there a work around?
I am not sure I understand your question. What do you mean by keyed in option 1? If you want to access those by 1, 2 or 3, you will have assign it to a new dict and use that dict to get the value.
@yongjie Please check the updated answer. It is just an extension of the comment I have added above.
Hi, Thanks again for your help, it has been very helpful but may I ask if I would like to sort said dict in reverse how may I go about doing so? I have tried res = dict(enumerate(sorted(Dairy_goods.values(), key=lambda x: x['price']),start=1,reverse=True)) but would give me an error.
There is a typo in what you have tried. reverse=True should be inside sorted function and not in enumerate.
|
1

Basically, you have a list of tuples that you want to sort by some values. Since tuples are the "units" you want to sort, you can't decompose the values of each tuple while sorting the tuples.

Anyway, you can achieve the expected output by:

  1. Sorting the tuples by x[1]['item'] as you did
  2. Re-numbering the results in their order in the list (by using enumerate for example, as AKS suggested in the other answer

Comments

0

You could do this.

  • Sort the values of dictionary by 'item'
  • Use enumerate to assign serial values to the sorted values
  • Convert that enumerate object to a list to get desired output
d = {1:{'item':'Milk','price':2.47,'gst':0.16,'offer':'Yes'},
    2:{'item':'Butter','price':4.50,'gst':0.32,'offer':'No',},
    3:{'item':'Egg','price':3.40,'gst':0.24,'offer':'No'}}
    
x = list(enumerate(sorted(d.values(), key= lambda x: x['item']), start=1))
print(x)
[(1, {'item': 'Butter', 'price': 4.5, 'gst': 0.32, 'offer': 'No'}), (2, {'item': 'Egg', 'price': 3.4, 'gst': 0.24, 'offer': 'No'}), (3, {'item': 'Milk', 'price': 2.47, 'gst': 0.16, 'offer': 'Yes'})]

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.