Re: [Tutor] samples on sort method of sequence object.

2010-01-14 Thread Stefan Behnel

Lie Ryan, 14.01.2010 01:47:

On 01/14/10 06:56, Hugo Arts wrote:

On Wed, Jan 13, 2010 at 8:21 PM, Stefan Behnel stefan...@behnel.de wrote:

Hugo Arts, 13.01.2010 15:25:

Here is my solution for the general case:

from itertools import groupby
def alphanum_key(string):
   t = []
   for isdigit, group in groupby(string, str.isdigit):
   group = ''.join(group)
   t.append(int(group) if isdigit else group)
   return t

Note that this won't work in Py3, where integers and strings are not
ordered, i.e. not comparable w.r.t the  and  operators.


True. You can accommodate by writing a ComparableInt class extending
int, and implement __lt__ and __gt__.
It's not exactly succinct, but it works.


Not necessary, you can just pass the cmp= parameter to sort that checks
the chunk's type.


Note that this won't work in Py3, where the cmp parameter is gone.

Stefan

___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] samples on sort method of sequence object.

2010-01-14 Thread Hugo Arts
On Thu, Jan 14, 2010 at 10:13 AM, Stefan Behnel stefan...@behnel.de wrote:

 Note that this won't work in Py3, where the cmp parameter is gone.

 Stefan

And he's right again. I should've checked for that. Well, that makes a
CmpInt class the only other solution:

class CmpInt(int):
def __lt__(self, other):
if isinstance(other, str): return True
return int.__lt__(self, other)
def __gt__(self, other):
if isinstance(other, str): return False
return int.__gt__(self, other)

Hugo
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] samples on sort method of sequence object.

2010-01-13 Thread Albert-Jan Roskam
Interesting. Can this also be used to make sorting of alphanumerical list items 
in a 'numerical' way easier? E.g.:
 x
['var_0', 'var_13', 'var_11', 'var_9', 'var_4', 'var_1', 'var_5', 'var_6', 
'var_7', 'var_14', 'var_2', 'var_3', 'var_8', 'var_10', 'var_12']
 x.sort()
 x
['var_0', 'var_1', 'var_10', 'var_11', 'var_12', 'var_13', 'var_14', 'var_2', 
'var_3', 'var_4', 'var_5', 'var_6', 'var_7', 'var_8', 'var_9']
 
 
This clearly does not give the desired result. I once solved this by making a 
dictionary of which the keys are zfilled versions of the list items (e.g. 
var_01, etc), then sort the keys, get the dictionary values in the right order, 
etc. It seemed a cumbersome way. Isn't there an easier way to sort x?

Cheers!!
Albert-Jan

~~
In the face of ambiguity, refuse the temptation to guess.
~~

--- On Tue, 1/12/10, Kent Johnson ken...@tds.net wrote:


From: Kent Johnson ken...@tds.net
Subject: Re: [Tutor] samples on sort method of sequence object.
To: Make Twilight ph4...@gmail.com
Cc: tutor@python.org
Date: Tuesday, January 12, 2010, 7:53 PM


On Tue, Jan 12, 2010 at 9:39 AM, Make Twilight ph4...@gmail.com wrote:

  I can understand how to use parameters of cmp and reverse,except the
 key parameter...
  Would anyone give me an example of using sort method with key parameter?

http://personalpages.tds.net/~kent37/kk/7.html
Kent
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor



  ___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] samples on sort method of sequence object.

2010-01-13 Thread Stefan Behnel

Albert-Jan Roskam, 13.01.2010 13:51:

Interesting. Can this also be used to make sorting of alphanumerical list items 
in a 'numerical' way easier? E.g.:

x

['var_0', 'var_13', 'var_11', 'var_9', 'var_4', 'var_1', 'var_5', 'var_6', 
'var_7', 'var_14', 'var_2', 'var_3', 'var_8', 'var_10', 'var_12']

x.sort()
x

['var_0', 'var_1', 'var_10', 'var_11', 'var_12', 'var_13', 'var_14', 'var_2', 
'var_3', 'var_4', 'var_5', 'var_6', 'var_7', 'var_8', 'var_9']
 
This clearly does not give the desired result. I once solved this by making a dictionary of which the keys are zfilled versions of the list items (e.g. var_01, etc), then sort the keys, get the dictionary values in the right order, etc. It seemed a cumbersome way. Isn't there an easier way to sort x?


   x.sort(key = lambda name: int(name.split('_')[-1]))

Stefan

___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] samples on sort method of sequence object.

2010-01-13 Thread Sander Sweers
2010/1/13 Albert-Jan Roskam fo...@yahoo.com

 Interesting. Can this also be used to make sorting of alphanumerical list 
 items in a 'numerical' way easier?
  x
 ['var_0', 'var_13', 'var_11', 'var_9', 'var_4', 'var_1', 'var_5', 'var_6', 
 'var_7', 'var_14', 'var_2', 'var_3', 'var_8', 'var_10', 'var_12']

Yes.
 x
['var_0', 'var_13', 'var_11', 'var_9', 'var_4', 'var_1', 'var_5',
'var_6', 'var_7', 'var_14', 'var_2', 'var_3', 'var_8', 'var_10',
'var_12']
 sorted(x, key=lamda x: int(x.strip('var_')))
SyntaxError: invalid syntax
 sorted(x, key=lambda x: int(x.strip('var_')))
['var_0', 'var_1', 'var_2', 'var_3', 'var_4', 'var_5', 'var_6',
'var_7', 'var_8', 'var_9', 'var_10', 'var_11', 'var_12', 'var_13',
'var_14']

Greets
Sander
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] samples on sort method of sequence object.

2010-01-13 Thread Albert-Jan Roskam
Very concise == neat solutions. Yummy. ;-) Thanks for your replies!

Cheers!!
Albert-Jan

~~
In the face of ambiguity, refuse the temptation to guess.
~~

--- On Wed, 1/13/10, Sander Sweers sander.swe...@gmail.com wrote:


From: Sander Sweers sander.swe...@gmail.com
Subject: Re: [Tutor] samples on sort method of sequence object.
To: Albert-Jan Roskam fo...@yahoo.com
Cc: *tutor python tutor@python.org
Date: Wednesday, January 13, 2010, 2:14 PM


2010/1/13 Albert-Jan Roskam fo...@yahoo.com

 Interesting. Can this also be used to make sorting of alphanumerical list 
 items in a 'numerical' way easier?
  x
 ['var_0', 'var_13', 'var_11', 'var_9', 'var_4', 'var_1', 'var_5', 'var_6', 
 'var_7', 'var_14', 'var_2', 'var_3', 'var_8', 'var_10', 'var_12']

Yes.
 x
['var_0', 'var_13', 'var_11', 'var_9', 'var_4', 'var_1', 'var_5',
'var_6', 'var_7', 'var_14', 'var_2', 'var_3', 'var_8', 'var_10',
'var_12']
 sorted(x, key=lamda x: int(x.strip('var_')))
SyntaxError: invalid syntax
 sorted(x, key=lambda x: int(x.strip('var_')))
['var_0', 'var_1', 'var_2', 'var_3', 'var_4', 'var_5', 'var_6',
'var_7', 'var_8', 'var_9', 'var_10', 'var_11', 'var_12', 'var_13',
'var_14']

Greets
Sander



  ___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] samples on sort method of sequence object.

2010-01-13 Thread Hugo Arts
I should note that this doesn't solve the general case of mixed
numeric/alphabetic sorting:

 a = ['a_1', 'a_2', 'a_3', 'a_4', 'a_10', 'b_1', 'b_2', 'b_3', 'b_4',
'b_10']
 a.sort(key=lambda x: int(x.split('_')[-1]))
 a
['a_1', 'b_1', 'a_2', 'b_2', 'a_3', 'b_3', 'a_4', 'b_4', 'a_10', 'b_10']

It only works if the alphabetic part of the string is the same everywhere,
and it doesn't work with a collection where some numbers appear before, some
after, etc.

Here is my solution for the general case:

from itertools import groupby
def alphanum_key(string):
t = []
for isdigit, group in groupby(string, str.isdigit):
group = ''.join(group)
t.append(int(group) if isdigit else group)
return t

or, in a oneliner:

 alphanum_key = lambda x: tuple((int(''.join(g)) if k else ''.join(g))
for k, g in groupby(x, str.isdigit))

that's equivalent, but not very readable. It works by grouping sequences of
numbers and not numbers together, and treating the number sequences as
integers rather than strings.

 a = ['0a', '1a', '10a', 'a1', 'a2', 'a10', 'a11', 'b2', 'b3', 'b20']
 a.sort()
 a
['0a', '10a', '1a', 'a1', 'a10', 'a11', 'a2', 'b2', 'b20', 'b3']
 # regular sort messes up because 'a10' is alphabetically before 'a2'.
now with alphanumeric sort:
 a.sort(key=alphanum_key)
 a
['0a', '1a', '10a', 'a1', 'a2', 'a10', 'a11', 'b2', 'b3', 'b20']

Hugo

On Wed, Jan 13, 2010 at 2:32 PM, Albert-Jan Roskam fo...@yahoo.com wrote:

  Very concise == neat solutions. Yummy. ;-) Thanks for your replies!


 Cheers!!
 Albert-Jan

 ~~
 In the face of ambiguity, refuse the temptation to guess.
 ~~

 --- On *Wed, 1/13/10, Sander Sweers sander.swe...@gmail.com* wrote:


 From: Sander Sweers sander.swe...@gmail.com

 Subject: Re: [Tutor] samples on sort method of sequence object.
 To: Albert-Jan Roskam fo...@yahoo.com
 Cc: *tutor python tutor@python.org
 Date: Wednesday, January 13, 2010, 2:14 PM


 2010/1/13 Albert-Jan Roskam 
 fo...@yahoo.comhttp://us.mc1107.mail.yahoo.com/mc/compose?to=fo...@yahoo.com
 
 
  Interesting. Can this also be used to make sorting of alphanumerical list
 items in a 'numerical' way easier?
   x
  ['var_0', 'var_13', 'var_11', 'var_9', 'var_4', 'var_1', 'var_5',
 'var_6', 'var_7', 'var_14', 'var_2', 'var_3', 'var_8', 'var_10', 'var_12']

 Yes.
  x
 ['var_0', 'var_13', 'var_11', 'var_9', 'var_4', 'var_1', 'var_5',
 'var_6', 'var_7', 'var_14', 'var_2', 'var_3', 'var_8', 'var_10',
 'var_12']
  sorted(x, key=lamda x: int(x.strip('var_')))
 SyntaxError: invalid syntax
  sorted(x, key=lambda x: int(x.strip('var_')))
 ['var_0', 'var_1', 'var_2', 'var_3', 'var_4', 'var_5', 'var_6',
 'var_7', 'var_8', 'var_9', 'var_10', 'var_11', 'var_12', 'var_13',
 'var_14']

 Greets
 Sander



 ___
 Tutor maillist  -  Tutor@python.org
 To unsubscribe or change subscription options:
 http://mail.python.org/mailman/listinfo/tutor


___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] samples on sort method of sequence object.

2010-01-13 Thread Stefan Behnel

Hugo Arts, 13.01.2010 15:25:

Here is my solution for the general case:

from itertools import groupby
def alphanum_key(string):
t = []
for isdigit, group in groupby(string, str.isdigit):
group = ''.join(group)
t.append(int(group) if isdigit else group)
return t


Note that this won't work in Py3, where integers and strings are not 
ordered, i.e. not comparable w.r.t the  and  operators.


Stefan

___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] samples on sort method of sequence object.

2010-01-13 Thread Hugo Arts
On Wed, Jan 13, 2010 at 8:21 PM, Stefan Behnel stefan...@behnel.de wrote:
 Hugo Arts, 13.01.2010 15:25:

 Here is my solution for the general case:

 from itertools import groupby
 def alphanum_key(string):
    t = []
    for isdigit, group in groupby(string, str.isdigit):
        group = ''.join(group)
        t.append(int(group) if isdigit else group)
    return t

 Note that this won't work in Py3, where integers and strings are not
 ordered, i.e. not comparable w.r.t the  and  operators.


True. You can accommodate by writing a ComparableInt class extending
int, and implement __lt__ and __gt__.
It's not exactly succinct, but it works.
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] samples on sort method of sequence object.

2010-01-13 Thread Kent Johnson
On Wed, Jan 13, 2010 at 2:21 PM, Stefan Behnel stefan...@behnel.de wrote:
 Hugo Arts, 13.01.2010 15:25:

 Here is my solution for the general case:

 from itertools import groupby
 def alphanum_key(string):
    t = []
    for isdigit, group in groupby(string, str.isdigit):
        group = ''.join(group)
        t.append(int(group) if isdigit else group)
    return t

 Note that this won't work in Py3, where integers and strings are not
 ordered, i.e. not comparable w.r.t the  and  operators.

It will work fine if all the list items have the same format which I
would think is the most common case.

Kent
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] samples on sort method of sequence object.

2010-01-13 Thread Lie Ryan
On 01/14/10 06:56, Hugo Arts wrote:
 On Wed, Jan 13, 2010 at 8:21 PM, Stefan Behnel stefan...@behnel.de wrote:
 Hugo Arts, 13.01.2010 15:25:

 Here is my solution for the general case:

 from itertools import groupby
 def alphanum_key(string):
t = []
for isdigit, group in groupby(string, str.isdigit):
group = ''.join(group)
t.append(int(group) if isdigit else group)
return t

 Note that this won't work in Py3, where integers and strings are not
 ordered, i.e. not comparable w.r.t the  and  operators.

 
 True. You can accommodate by writing a ComparableInt class extending
 int, and implement __lt__ and __gt__.
 It's not exactly succinct, but it works.

Not necessary, you can just pass the cmp= parameter to sort that checks
the chunk's type.

___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] samples on sort method of sequence object.

2010-01-13 Thread Hugo Arts
On Thu, Jan 14, 2010 at 1:47 AM, Lie Ryan lie.1...@gmail.com wrote:
 On 01/14/10 06:56, Hugo Arts wrote:
 On Wed, Jan 13, 2010 at 8:21 PM, Stefan Behnel stefan...@behnel.de wrote:
 Hugo Arts, 13.01.2010 15:25:

 Here is my solution for the general case:

 from itertools import groupby
 def alphanum_key(string):
    t = []
    for isdigit, group in groupby(string, str.isdigit):
        group = ''.join(group)
        t.append(int(group) if isdigit else group)
    return t

 Note that this won't work in Py3, where integers and strings are not
 ordered, i.e. not comparable w.r.t the  and  operators.


 True. You can accommodate by writing a ComparableInt class extending
 int, and implement __lt__ and __gt__.
 It's not exactly succinct, but it works.

 Not necessary, you can just pass the cmp= parameter to sort that checks
 the chunk's type.


might be interesting to see which performs better. cmp is called more
often, but replacing C versions of __lt__ and __gt__ with python
versions slows things down also, I would presume.

Hugo
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor


[Tutor] samples on sort method of sequence object.

2010-01-12 Thread Make Twilight
Hi,there:
  The document of
Python.org[http://docs.python.org/library/stdtypes.html] says that:
  
--
  s.sort([cmp[, key[, reverse]]])

  8. The sort() method takes optional arguments for controlling the comparisons.

  cmp specifies a custom comparison function of two arguments
(list items) which should return a negative, zero or positive number
depending on whether the first argument is considered smaller than,
equal to, or larger than the second argument: cmp=lambda x,y:
cmp(x.lower(), y.lower()). The default value is None.

 key specifies a function of one argument that is used to extract
a comparison key from each list element: key=str.lower. The default
value is None.

 reverse is a boolean value. If set to True, then the list
elements are sorted as if each comparison were reversed.
  

  I can understand how to use parameters of cmp and reverse,except the
key parameter...
  Would anyone give me an example of using sort method with key parameter?
  Thanks!


--
ph4...@gmail.com
Mak Twilight
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] samples on sort method of sequence object.

2010-01-12 Thread Hugo Arts
On Tue, Jan 12, 2010 at 3:39 PM, Make Twilight ph4...@gmail.com wrote:
 Hi,there:
  The document of
 Python.org[http://docs.python.org/library/stdtypes.html] says that:

 snip

  I can understand how to use parameters of cmp and reverse,except the
 key parameter...
  Would anyone give me an example of using sort method with key parameter?
  Thanks!


key has essentially the same purpose as cmp, but it works more
efficiently because it only calls the key function once for each value
in the sequence. A simple though maybe not very useful example could
be sorting lists of integers in such a way that the list with the
lowest sum comes first:

 seqs = [(2, 0, 0), (3, 5, 5), (1, 100, 100)]
 seqs.sort()
 seqs
[(1, 100, 100), (2, 0, 0), (3, 5, 5)]
 seqs.sort(key=sum)
 seqs
[(2, 0, 0), (3, 5, 5), (1, 100, 100)]

the sort function calls the key function sum(s) for every s in
sequence, then sorts the list using the result of that call. An
equivalent example using the cmp function could be this one:

 seqs.sort(cmp=lambda x, y: cmp(sum(x), sum(y))

Another example given by the docs is using the str.lower function.
Here it is in action:

 s = list(A string WitH Some Capitals)
 s.sort(key=str.lower)
 s
[' ', ' ', ' ', ' ', 'A', 'a', 'a', 'C', 'e', 'g', 'H', 'i', 'i', 'i',
'l', 'm', 'n', 'o', 'p', 'r', 's', 'S', 's', 't', 't', 't', 'W']
 s.sort()
 s
[' ', ' ', ' ', ' ', 'A', 'C', 'H', 'S', 'W', 'a', 'a', 'e', 'g', 'i',
'i', 'i', 'l', 'm', 'n', 'o', 'p', 'r', 's', 's', 't', 't', 't']

Normally, when sorting a string, capital letters come before regular
ones. With the key() argument, the sorting is done between the lowered
versions of each letter, so the sort becomes case insensitive. Note
that this doesn't actually change our string, it only changes what
exactly is used for our comparisons. Again, same sort using the cmp
argument:

s.sort(cmp=lambda x, y: cmp(x.lower(), y.lower())

Hugo
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] samples on sort method of sequence object.

2010-01-12 Thread Kent Johnson
On Tue, Jan 12, 2010 at 9:39 AM, Make Twilight ph4...@gmail.com wrote:

  I can understand how to use parameters of cmp and reverse,except the
 key parameter...
  Would anyone give me an example of using sort method with key parameter?

http://personalpages.tds.net/~kent37/kk/7.html
Kent
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor