#1
  1. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Mar 2013
    Posts
    8
    Rep Power
    0

    [SOLVED] How do you apply the function in sort()?


    I need an exhaustive explanation of how to apply the function in sort(). I have seen terms like "lambda" and "key", but have been unable to find any documentation on how to apply them or what they mean.

    Any and all tips or clues would be appreciated.
  2. #2
  3. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jul 2007
    Location
    Joensuu, Finland
    Posts
    439
    Rep Power
    67
    Originally Posted by DSPksky
    I need an exhaustive explanation of how to apply the function in sort().
    It’s hard to be more exhaustive than the official documentation:

    ”key specifies a function of one argument that is used to extract a comparison key from each list element (for example, key=str.lower). The key corresponding to each item in the list is calculated once and then used for the entire sorting process. The default value of None means that list items are sorted directly without calculating a separate key value.”

    That is, when you call the sort() method (or the sort() function) like this:

    Code:
    somelist.sort(key=somefunc)
    ...you send the elements of “somelist” to the function “somefunc” and get comparison keys as results. If the function you’re calling is simple enough you can use a nameless lambda function in its place.

    I have used that for example when I needed to sort letters with diacritics. The function I called took, say, “Čistovič”, and returned “Cistovic” so that the name wouldn’t be sorted at the end of the alphabet.
    My armada: openSUSE 13.2 (home desktop, work desktop), openSUSE 13.1 (home laptop), Debian GNU/Linux 7.7.0 (mini laptop), Ubuntu 14.04 LTS (server), Android 4.2.1 (tablet), Windows 7 Ultimate (testbed)
  4. #3
  5. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Mar 2013
    Posts
    8
    Rep Power
    0

    OK, better ...


    I've seen the documentation, but "lambda" is not explained and the example doesn't help.

    str.lower() is a function I see that converts upper case to lower case. Is this the same function? How is it used to compare for a sort?

    I need a better explanation of the formalism use to apply a function in sort().
  6. #4
  7. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jul 2007
    Location
    Joensuu, Finland
    Posts
    439
    Rep Power
    67
    Originally Posted by DSPksky
    I've seen the documentation, but "lambda" is not explained and the example doesn't help.
    It’s really not about the lambda; lambda is just used to create nameless functions when the function body is so short you don’t want to waste writing a “def somefunc():” style definition.

    Say that your list contained tuples instead of strings and you want to sort based on the first element of the tuple, not caring about the rest of it, you might do:

    Code:
    somelist.sort(key=lambda t: t[0])
    That is, take a tuple (or any sequence that can be sliced) “t” and sort based only on the first element of it. If you don’t like lambdas, you could do:

    Code:
    def takefirst(t):
        return t[0]
    
    somelist.sort(key=takefirst)
    str.lower() is a function I see that converts upper case to lower case. Is this the same function? How is it used to compare for a sort?
    Same function as what? str.lower() is used to make sure every element of the sequence is in lowercase so that the sorting will be case-insensitive.
    My armada: openSUSE 13.2 (home desktop, work desktop), openSUSE 13.1 (home laptop), Debian GNU/Linux 7.7.0 (mini laptop), Ubuntu 14.04 LTS (server), Android 4.2.1 (tablet), Windows 7 Ultimate (testbed)
  8. #5
  9. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Mar 2013
    Posts
    8
    Rep Power
    0

    better...


    Here is a tutorial that is also helping:

    https://developers.google.com/edu/python/sorting

    You might have to register with google to see the page. I see the "https" there.

    OK, I'm getting it. 'lambda' is sort of like an anonymous function in perl, if I remember correctly.

    I am working with pulling data out of MySQL database and so I am also trying to figure out the data structure of what I get from a query. I think I get a tuple of tuples.

    This is not working yet,

    Code:
    cursor.execute("SELECT ... <your query to select a single field goes here>") 
    
    results = cursor.fetchall()
    
    srt = sorted(results, key=len)
    
    print srt
    
    print results
    What I hope to do is sort the results by the length of the entry in each field.

    This doesn't work either,

    Code:
    srt = sorted(key=lambda results: len(results[0]))
  10. #6
  11. Contributing User
    Devshed Demi-God (4500 - 4999 posts)

    Join Date
    Aug 2011
    Posts
    4,995
    Rep Power
    481
    Key gives us a new numerical method!
    Find the minimum of a function over some domain.
    Sort based on f(x)

    Code:
    >>> def y(x):
    ...  return x*(x-3)
    ... 
    >>> x = list(range(12))
    >>> x.sort(key=y)
    >>> x
    [1, 2, 0, 3, 4, 5, 6, 7, 8, 9, 10, 11]
    >>>
    The minimum occurs as close to x==1 as to any other value in the list.
    -b/(2a) is the abscissa, 3/2 .
    [code]Code tags[/code] are essential for python code and Makefiles!
  12. #7
  13. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Mar 2013
    Posts
    8
    Rep Power
    0

    I am having some data problems


    Here is some sample data representing the problem I am having:

    Code:
    tuple_tuples = (('ZACHARY HITE',), ('RICHARD MCCRARY',), ('DIANA ALEXANDER',),
        ('SCOTT SHELLEY',), ('CLINTON BUFORD',), ('WILMA RICHARDS',), 
        ('BETTY WHITE',),
        )
    tuple_tuples.sort() does not work and gives an error,

    "AttributeError: 'tuple' object has no attribute 'sort'"

    sorted(tuple_tuples) does work and sorts by the first letter of the first and only entry of each tuple entry.

    sorted(len(tuple_tuples)) doesn't work and gives an error,

    "TypeError: 'int' object is not iterable"

    I am trying to do one of two things. I am trying to either sort the list of tuples according to the length of each entry, or I would like to retrieve the longest length of the entries in the list of tuples. (tuple of tuples, more properly, I guess)
  14. #8
  15. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jul 2007
    Location
    Joensuu, Finland
    Posts
    439
    Rep Power
    67
    Originally Posted by DSPksky
    tuple_tuples.sort() does not work and gives an error,

    "AttributeError: 'tuple' object has no attribute 'sort'"
    Yap, tuples are immutable. You need to convert it to a list first.

    sorted(len(tuple_tuples)) doesn't work and gives an error,

    "TypeError: 'int' object is not iterable"
    Of course: you are now trying to sort an integer, namely the length of tuple_tuples! Forgot “key=” already?

    Anywho, do it this way:

    Code:
    t = list(tuple_tuples) # to get a mutable object
    t.sort(key=lambda tup: len(tup[0]))
    My armada: openSUSE 13.2 (home desktop, work desktop), openSUSE 13.1 (home laptop), Debian GNU/Linux 7.7.0 (mini laptop), Ubuntu 14.04 LTS (server), Android 4.2.1 (tablet), Windows 7 Ultimate (testbed)
  16. #9
  17. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Mar 2013
    Posts
    8
    Rep Power
    0
    Thanks, SuperOscar. That did it.

    I had hoped there was some way of converting the tuple of tuples into a list of tuples, but nothing in my sources on line had anything like that.

    I understand the application of lambda, but the function abstraction still has me a little confused. In your ealier example, you had,

    Code:
    def takefirst(t):
    	return t[0]
    
    somelist.sort(key=takefirst)
    As a function running in a regular program, this will do nothing but return the first element in the list t. How does that become something that handles every element in the list?


    b49P23TIvg's example is similar,

    Code:
    def y(x):
    	return x*(x-3)
    
    x.sort(key=y)
    The function takes each element of x, x is a list, not an integer and y(x) makes no sense if x is a list.

    How does the function applied to one type become a function applied to some other type and how do you keep track of what type becomes the other type?

    If x is a list of tuples, then x.sort() just sorts the list of tuples according to the first entry of each tuple, alphabetically. Where and how does the function sort() isolate the element of a list as being something other than a list itself?
  18. #10
  19. Contributing User
    Devshed Demi-God (4500 - 4999 posts)

    Join Date
    Aug 2011
    Posts
    4,995
    Rep Power
    481
    x.sort(key=y)

    sort is a method of the object x. It's not a function.
    ListObject.sort() orders the objects in ListObject by whatever comparison is defined for objects in the list.

    Code:
    # And here, for the confusion value:
    class c:
        def sort(*args):  # method with a poorly chosen name
            return 666
    
    assert c().sort() == 666
    [code]Code tags[/code] are essential for python code and Makefiles!
  20. #11
  21. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Mar 2013
    Posts
    8
    Rep Power
    0

    More confusion ...


    http://python.org Here's another clue,

    Code:
    t.sort(key=lambda tup: len(tup[0]), reverse=True)
    This is how you would reverse the order of that sort.

    There is no accessible documentation for this anywhere. There is an official website, http://python.org and related, an official documentation site, http://python.org/doc but if there is any information there on this, I don't know where it is or how to find it.
  22. #12
  23. Contributing User
    Devshed Demi-God (4500 - 4999 posts)

    Join Date
    Aug 2011
    Posts
    4,995
    Rep Power
    481
    Where do you come up with "no accessible documentation"?
    Code:
    >>> help (list.sort)
    Help on method_descriptor:
    
    sort(...)
        L.sort(key=None, reverse=False) -- stable sort *IN PLACE*
    HERE http://docs.python.org/3/library/stdtypes.html#lists

    And what is not clear about
    Originally Posted by http://docs.python.org/3/
    Library Reference
    keep this under your pillow
    ?


    google `python list sort' has eleven million hits.
    Last edited by b49P23TIvg; March 28th, 2013 at 04:25 PM.
    [code]Code tags[/code] are essential for python code and Makefiles!
  24. #13
  25. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jul 2007
    Location
    Joensuu, Finland
    Posts
    439
    Rep Power
    67
    Originally Posted by DSPksky
    I had hoped there was some way of converting the tuple of tuples into a list of tuples, but nothing in my sources on line had anything like that.
    Often you can just try if Python directly converts from one type to another, as in this case.

    As a function running in a regular program, this will do nothing but return the first element in the list t. How does that become something that handles every element in the list?
    The key is in the name of the named method argument, “key”. With key=somefunc, somefunc() is called to turn the actual sequence elements into values that the sorting will be based on. So, “key=lambda tup: len(tup[0])” takes one element at a time from the sequence that is to be sorted, treats that element as a sequence, picks the first element in that sequence, and returns its length.

    You might picture it this way: you are not directly sorting the list:

    Code:
    [('ZACHARY HITE',), ('RICHARD MCCRARY',), ...]
    but a different list where the integers stand for the string lengths:

    Code:
    [12, 14, ...]
    and only then sort the first list based on the order of the second list, sorted.
    My armada: openSUSE 13.2 (home desktop, work desktop), openSUSE 13.1 (home laptop), Debian GNU/Linux 7.7.0 (mini laptop), Ubuntu 14.04 LTS (server), Android 4.2.1 (tablet), Windows 7 Ultimate (testbed)
  26. #14
  27. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Mar 2013
    Posts
    8
    Rep Power
    0

    I'm done.


    That all helps. Thanks to all who posted.

    From the linked documentation,

    http://docs.python.org/3/library/stdtypes.html#lists

    key specifies a function of one argument that is used to extract a comparison key from each list element (for example, key=str.lower). The key corresponding to each item in the list is calculated once and then used for the entire sorting process. The default value of None means that list items are sorted directly without calculating a separate key value.
    So the function is not applied to the list, but to individual members of the list and is broad enough to include transformations of type as well. The last thing done is always a sort and no matter how you apply the key, a sort is what you always get.

    I remember running into this functionality in C++ and had a hard time with it then. This functionality can be abstracted to other kinds of relationships within a list, if I recall correctly.
  28. #15
  29. Contributing User
    Devshed Demi-God (4500 - 4999 posts)

    Join Date
    Aug 2011
    Posts
    4,995
    Rep Power
    481
    Code:
    $ python3
    Python 3.2.3 (default, Oct 19 2012, 19:53:16) 
    [GCC 4.7.2] on linux2
    Type "help", "copyright", "credits" or "license" for more information.
    >>> 8 < 'a'
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    TypeError: unorderable types: int() < str()
    >>>
    Code:
    $ python
    Python 2.7.3 (default, Sep 26 2012, 21:51:14) 
    [GCC 4.7.2] on linux2
    Type "help", "copyright", "credits" or "license" for more information.
    >>> 1 < 'a'
    True
    >>>
    [code]Code tags[/code] are essential for python code and Makefiles!

IMN logo majestic logo threadwatch logo seochat tools logo