954,549 Members — Technology Publication meets Social Media
Username:
Password:
Lost login information?
Have something to say? Contribute New Article Reply to this Article

min/max of a mixed type list

I took a mixed type list and set out to find the min and max values. The results are very surprising to me:
[php]mixed_list = [11, 'Dick', 12, 'Mary', 7, 'Zoe', 9, 700, 777, 'Paul', 13456789]
mn = min(mixed_list)
mx = max(mixed_list)
print mn, type(mn) # 7
print mx, type(mx) # Zoe
[/php]How does Python handle mixed type lists to get such a result?

sneekula
Nearly a Posting Maven
2,427 posts since Oct 2006
Reputation Points: 961
Solved Threads: 212
 
How does Python handle mixed type lists to get such a result?

Pretty much, all pc's use ascii encoding and sort in "ascii order", see http://www.asciitable.com/

woooee
Nearly a Posting Maven
2,454 posts since Dec 2006
Reputation Points: 777
Solved Threads: 714
 
I took a mixed type list and set out to find the min and max values.


What results have you expected? Is "Dick" larger than 12 or smaller? (I mean the string "Dick", ... :)).
Here's what the docu says:Note that comparing objects of different types is legal. The outcome is deterministic but arbitrary: the types are ordered by their name. Thus, a list is always smaller than a string, a string is always smaller than a tuple, etc. Mixed numeric types are compared according to their numeric value, so 0 equals 0.0, etc.
And in a footnote:The rules for comparing objects of different types should not be relied upon; they may change in a future version of the language.

mawe
Junior Poster
133 posts since Sep 2005
Reputation Points: 19
Solved Threads: 58
 

Thanks mawe,

originally I thought it was by ascii value, but then 11 would have been the min value since ascii 1 is lower than ascii 7. So the order in the list was more like:

[7, 9, 11, 12, 700, 777, 13456789, 'Dick', 'Mary', 'Paul', 'Zoe']
Is there a way to get a min/max of each type?

sneekula
Nearly a Posting Maven
2,427 posts since Oct 2006
Reputation Points: 961
Solved Threads: 212
 

Well, here's the first thing that came to my mind:

In [17]: lst = [5, "Paul", 4, 2, "Mary", 1, "Dick", "Zoe", 3]
In [18]: min_num = min( i for i in lst if isinstance(i, int) )

In [19]: min_str = min( i for i in lst if isinstance(i, str) )

In [20]: min_num
Out[20]: 1

In [21]: min_str
Out[21]: 'Dick'

It works, but there must be something more clever. I'll think about it ...

mawe
Junior Poster
133 posts since Sep 2005
Reputation Points: 19
Solved Threads: 58
 
originally I thought it was by ascii value, but then 11 would have been the min value since ascii 1 is lower than ascii 7.

11 is only less than 7 on the planet Bizarro, and any number AFAIK is sorted before letters so they are all first, because any digit is less than any character. Note that there is a difference between 11 (decimal 11) and '11' (decimal 49, decimal 49) and they will be sorted differently.

woooee
Nearly a Posting Maven
2,454 posts since Dec 2006
Reputation Points: 777
Solved Threads: 714
 
I took a mixed type list and set out to find the min and max values. The results are very surprising to me: [php]mixed_list = [11, 'Dick', 12, 'Mary', 7, 'Zoe', 9, 700, 777, 'Paul', 13456789] mn = min(mixed_list) mx = max(mixed_list) print mn, type(mn) # 7 print mx, type(mx) # Zoe [/php]How does Python handle mixed type lists to get such a result?

another way...but you have to test it in different cases...

lst = [11, 'Dick', 12, 'Mary', 7, 'Zoe', 9, 700, 777, 'Paul', 13456789]
slist = sorted(lst) #sort the list
min_num , max_str = slist[0],  slist[-1]  #first and last element usually is minnum, max str.
for num,item in enumerate(slist):
  try:
    if item.isalpha():  #check for first occurence of a word.
      min_str = item
      max_num = slist[num-1]  #get the number on the left of this word. Usually is max num
      break
  except: pass
print min_num ,max_num , max_str ,  min_str
ghostdog74
Junior Poster
156 posts since Apr 2006
Reputation Points: 75
Solved Threads: 44
 

If a sort would be purely by ASCII value then you would have to treat the list elements as strings ...

# convert all list items to type string ...
mixed_list = [11, 'Dick', 12, 'Mary', 7, 'Zoe', 9, 700, 777, 'Paul', 13456789]
str_list = [str(x) for x in mixed_list]
# now it's a pure ASCII sort ...
print sorted(str_list)
"""
output -->
['11', '12', '13456789', '7', '700', '777', '9', 'Dick', 'Mary', 'Paul', 'Zoe']
"""


I think that was what Sneekula originally though might have happened.

I leaned on mawe's idea and created a generic function to extract the min and max values of a given type from a mixed list ...

def minmax4(lst, typ):
    """return min/max of mixed list lst for items of type typ"""
    temp = [x for x in lst if isinstance(x, typ)]
    return min(temp), max(temp)
 
# minmax4() test ...
mixed_list = [11, 'Dick', 12, 'Mary', 7, 'Zoe', 9, 700, 777, 'Paul', 13456789]
print mixed_list
 
print "The min and max of the integers are:"
mn, mx = minmax4(mixed_list, int)
print "minimum = %s  maximum = %s" % (mn, mx)
 
print "The min and max of the strings are:"
mn, mx = minmax4(mixed_list, str)
print "minimum = %s  maximum = %s" % (mn, mx)
"""
minmax4() test output -->
[11, 'Dick', 12, 'Mary', 7, 'Zoe', 9, 700, 777, 'Paul', 13456789]
The min and max of the integers are:
minimum = 7  maximum = 13456789
The min and max of the strings are:
minimum = Dick  maximum = Zoe
"""
vegaseat
DaniWeb's Hypocrite
Moderator
5,989 posts since Oct 2004
Reputation Points: 1,345
Solved Threads: 1,417
 

This question has already been solved

Post: Markdown Syntax: Formatting Help
You