Python Forum
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
sorting
#11
in another project i ran into this issue with str vs int. but i can see potential cases where other types could be there, hence the the thought of using repr(). but i am not sure if that is even good enough. i wonder if json.dump() can handle all possible types or if pickle would be a better choice. oh wait, there are cases where even pickle can fail. the only final answer i can think of is to do try: and if there is an exception just use some fixed string like '?'.
Tradition is peer pressure from dead people

What do you call someone who speaks three languages? Trilingual. Two languages? Bilingual. One language? American.
Reply
#12
When would str() not work? If the object doesn't have __str__, it uses __repr__, and everything has __repr__, doesn't it? You would have to explicitly override __repr__ (or __str__) to throw an error to get a class that couldn't handle str().

If you don't like the ordering str() give you, that's a problem, but it's a problem of how do you order different types. There's no objective answer for that, and whatever subjective answer you come up with could be written into a function and used with key=.
Craig "Ichabod" O'Brien - xenomind.com
I wish you happiness.
Recommended Tutorials: BBCode, functions, classes, text adventures
Reply
#13
i use repr() to do printing of variables for diagnostic assistance.  it quotes actual string types so they can be recognized as strings.  but for sorting i now see that it is a bad choice where the order matters because the string content can cause the quotes to vary, or insert escape sequences, and disorganize the sorting order.

i vaguely remember there being cases where repr() failed and raised an exception with a traceback.  i do not recall what it did this on, but i probably need to add a lot of try/except code to my print_object() function.  i did not try str() on this case.  if i can recall it, i plan to play around with it in many ways.

sorting of unhashable and/or complex objects is inherently risky.  one must think about how they want their data to be ordered.  the type is likely to be as important as the value.

def pv(*names,**opts):
    p = '==>'
    for x in names:
        if not isinstance(x,(list,tuple)):
            x = [ x ]
        for name in x:
            name = str(name)
            d = inspect.currentframe().f_back.f_locals
            if name not in d:
                print(p, name, 'not assigned', **opts)
            else:
                print(p, name, '=', repr(d[name]), **opts)
    return
Tradition is peer pressure from dead people

What do you call someone who speaks three languages? Trilingual. Two languages? Bilingual. One language? American.
Reply
#14
I did this yesterday but had no time to write here.
Didn't try for other types.
In [1]: d = {1: 'one', 4: 'four', 3: 'three', 2: 'two', 'five': 5, 'six': 6, 'nine': 9, 'ten': 10, 'eight': 8, 'seven':7, 11: 'eleven'} 

In [2]: def sorted_dict(obj):
   ...:     nums = sorted([n for n in obj.keys() if isinstance(n, int)])
   ...:     strs = sorted([s for s in obj.keys() if isinstance(s, str)])
   ...:     d_keys = nums + strs
   ...:     return [(k, obj[k]) for k in d_keys]
   ...: 

In [3]: for k, v in sorted_dict(d):
   ...:     print(k, v)
   ...:     
1 one
2 two
3 three
4 four
11 eleven
eight 8
five 5
nine 9
seven 7
six 6
ten 10
"As they say in Mexico 'dosvidaniya'. That makes two vidaniyas."
https://freedns.afraid.org
Reply
#15
Simple sorting where numbers are sorted naturally and come before everything else could be achieved in python3 with:
In [5]: a = [3, 2.34, 1, 'string', '5th May', 11]

In [6]: sorted(a, key=lambda x: (0, x) if isinstance(x, (int, float)) else (1, str(x)))
Out[6]: [1, 2.34, 3, 11, '5th May', 'string']
As higher position elements are used only to resolve ties, it wont crash due to incomparable types.
Reply
#16
May you explain what is (0, x) tuple for and how this one liner is doing the same?
"As they say in Mexico 'dosvidaniya'. That makes two vidaniyas."
https://freedns.afraid.org
Reply
#17
Python tuples are sorted lexicographically (at first its sorted by first element, then second element is used to break ties, then third to break remaining ties and so on). So using (0, ..) and (1, ..) ensures that any item with key (0,..) comes before any item with key (1, ...). "Tie breaking" compares second elements only inside groups with same first element and these are comparable (for tuples starting with 0 they are all numbers, for tuples starting with 1 they are all strings), so it wont crash.
Reply
#18
nice, so str(x) is sorted as (1,str(x)).  so is str() safe for all other possible types ... other than silliness like putting classes in with data to be 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
#19
Yes, as Ichabod801 pointed out, str() should be quite secure.

But strings and other non numbers will be mixed up - you can expand this and use seperate key function that could do somethig like: x number -> (0, x), x string -> (1, x), x type A -> (2, str(x)), x type B -> (3, str(x)), x something else -> (4, str(x)) to enforce that different types would be sorted as you want. And you dont need to always use str, for some classes it could make sense to use other function. It all depends on what you want (and why).
Reply
#20
I still don't get it. Can you convert lambda x: (0, x) if isinstance(x, (int, float)) else (1, str(x))) to a normal function, please
"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,073 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