Python Forum
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
sorting
#1
the goal for a function to write is to print a dictionary in the order of the keys.  but then you have a case of a dictionary with some strings and some ints as keys.  python 3 does support order between unlike types (well any number type to any other number type should work).  this is ambiguous, anyway.   what will you do?
Tradition is peer pressure from dead people

What do you call someone who speaks three languages? Trilingual. Two languages? Bilingual. One language? American.
Reply
#2
I will turn it into a JSON and get it back. json.dump(dict, sort_keys=True)
"As they say in Mexico 'dosvidaniya'. That makes two vidaniyas."
https://freedns.afraid.org
Reply
#3
(Mar-15-2017, 04:40 AM)wavic Wrote: I will turn it into a JSON and get it back. json.dump(dict, sort_keys=True)

so when you load it back your dictionary is sorted?

(Mar-15-2017, 04:40 AM)wavic Wrote: I will turn it into a JSON and get it back. json.dump(dict, sort_keys=True)

so when you load it back your dictionary is sorted?
Tradition is peer pressure from dead people

What do you call someone who speaks three languages? Trilingual. Two languages? Bilingual. One language? American.
Reply
#4
You have a point. That was first crossed my mind. I miss my morning coffee. Anyway, I tried it and it throws TypeError: not supported between instances of 'str' and 'int'. But, as you say, you do not get back sorted dict after load it.

I will think about this later. Bussy now.
"As they say in Mexico 'dosvidaniya'. That makes two vidaniyas."
https://freedns.afraid.org
Reply
#5
Maybe I misunderstood something (as a dict has no inherited order of keys), but why not just print the dict using sort with key = str?

for key in sorted(my_dict, key=str):
    print(key, my_dict[key])
Or eventually convert it to / use OrderedDict from collections to preserve order?
from collections import OrderedDict

ord_dict = OrderedDict(((key, my_dict[key]) for key in sorted(my_dict, key=str)))
Reply
#6
i'm thinking of using the key= option of sorted() and in there making whatever conversion i need to make to have collatable values.  but do ints come before strings, after strings, or mingled in by some method such as str() or repr() might do.  i'm thinking repr() can handle most values and make a string.  i have run across a case that repr() failed on.  i'll need to recall that, reproduce it, and resolve it.
Tradition is peer pressure from dead people

What do you call someone who speaks three languages? Trilingual. Two languages? Bilingual. One language? American.
Reply
#7
Yes, with str or repr its representation would be sorted lexically, so if you have strings starting with a number, they will be mixed up. Perhaps define your key function that would respect your priorities according to the type of key?

An ugly example just for ilustration:
my_dict = {7: "int key", "2nd item":  "string key", 3.14159: "float key", 
          "e": "another string key", 2j: "complex key"}

def my_key(x):
    priority = {"int": 1, "str": 2, "float": 3}
    return (priority.get(x.__class__.__name__, 0), str(x))

for key in sorted(my_dict, key=my_key):
    print("{:<10} -> {}".format(key, my_dict[key]))
Output:
2j         -> complex key 7          -> int key 2nd item   -> string key e          -> another string key 3.14159    -> float key
Reply
#8
>>> d = {1: 'one', 4: 'four', 3: 'three', 2: 'two', 'five': 5, 'six': 6, 'nine':
... 9, 'ten': 10, 'eight': 8, 'seven':7} 

>>> d
{1: 'one', 4: 'four', 3: 'three', 2: 'two', 'five': 5, 'six': 6, 'nine': 9, 'ten': 10, 'eight': 8, 'seven': 7}

>>> sorted(d, key=lambda k: str(k) if type(k) == int  else k)
[1, 2, 3, 4, 'eight', 'five', 'nine', 'seven', 'six', 'ten']

>>> sorted(d, key=lambda k: str(k) if type(k) == int  else k)
[1, 2, 3, 4, 'eight', 'five', 'nine', 'seven', 'six', 'ten']

>>> d = {1: 'one', 4: 'four', 3: 'three', 2: 'two', 'five': 5, 'six': 6, 'nine':
... 9, 'ten': 10, 'eight': 8, 'seven':7, 11: 'eleven'} 

>>> sorted(d, key=lambda k: str(k) if type(k) == int  else k)
[1, 11, 2, 3, 4, 'eight', 'five', 'nine', 'seven', 'six', 'ten']
This works but has an issues as see.
"As they say in Mexico 'dosvidaniya'. That makes two vidaniyas."
https://freedns.afraid.org
Reply
#9
Isnt str(x) == x if x is a string? I am not sure if there is any difference between

sorted(d, key=str)
and
sorted(d, key = lambda x : str(x) if type(x) == int else x)
for keys being strings and ints.

And yes, if ints should be sorted as a numbers and before/after strings, something more complicated would be needed. Actually in python 2 comparison between numbers and strings works quite well naturally:
>>> sorted({4: 'four', 11: 'eleven', 1: 'one', 'ten': 10, 'seven': 7, 1.23: 'float'})
[1, 1.23, 4, 11, 'seven', 'ten']
Reply
#10
Hm! Didn't try it with python2.
"As they say in Mexico 'dosvidaniya'. That makes two vidaniyas."
https://freedns.afraid.org
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  Sorting a copied list is also sorting the original list ? SN_YAZER 3 3,101 Apr-11-2019, 05:10 PM
Last Post: SN_YAZER

Forum Jump:

User Panel Messages

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