[Tutor] Sorting list of tuples in two passes

Hugo Arts hugo.yoshi at gmail.com
Mon Aug 29 02:59:43 CEST 2011


On Mon, Aug 29, 2011 at 2:19 AM, Dayo Adewunmi <contactdayo at gmail.com> wrote:
> On 08/28/2011 06:23 PM, Hugo Arts wrote:
>>
>> On Sun, Aug 28, 2011 at 6:43 PM, Dayo Adewunmi<contactdayo at gmail.com>
>>  wrote:
>>>
>>> Hi
>>>
>>> I have a list of tuples that each have four elements:
>>>
>>> [(firstName,lastName,userName,gidNumber),(.....)....]
>>>
>>> I'm trying to sort this list in two passes. First by gidNumber and then
>>> the
>>> subgroups by lastName. So far i've only been able to sort by gidNumber.
>>> But
>>> I can't seem to wrap my mind around lambda, which is what my browsing
>>> around
>>> seems to indicate is needed to achieve this?
>>>
>>> Thanks
>>>
>>> Dayo
>>>
>> Python's builtin sort is stable, which means that ordering of items
>> with the same key is preserved. This property means that you can do
>> multiple pass sorting very easily and efficiently just by sorting
>> twice:
>>
>>>>> # we'll simplify the problem a bit and have tuples with just last name
>>>>> and id.
>>>>> l = [('aaa', 1), ('bbb', 1), ('ccc', 1), ('aaa', 2), ('bbb', 2),
>>>>> ('ccc', 2)]
>>>>> l.sort(key=itemgetter(0))
>>>>> l
>>
>> [('aaa', 1), ('aaa', 2), ('bbb', 1), ('bbb', 2), ('ccc', 1), ('ccc', 2)]
>>>>>
>>>>> l.sort(key=itemgetter(1))
>>>>> l
>>
>> [('aaa', 1), ('bbb', 1), ('ccc', 1), ('aaa', 2), ('bbb', 2), ('ccc', 2)]
>> We sort by last name first, then sort again by id. As you can see, the
>> sorting of groups with the same id is preserved, and our list is now
>> in the correct order.
>>
>> Hugo
>>
>
> It works when I use your example, but I don't understand why it won't work
> when I use 4-element tuples instead of 2:
>
>>>>l = [('wascas','aaa','fdvdfv', 1), ('rtgdsf','bbb','trfg', 1),
>>>> ('addwe','ccc','esd', 1), ('xasd','aaa','wascaq', 2), ('nhy','bbb','asw',
>>>> 2), ('zzzz','ccc','dgdeg', 2)]
>>>> l
> [('wascas', 'aaa', 'fdvdfv', 1), ('rtgdsf', 'bbb', 'trfg', 1), ('addwe',
> 'ccc', 'esd', 1), ('xasd', 'aaa', 'wascaq', 2), ('nhy', 'bbb', 'asw', 2),
> ('zzzz', 'ccc', 'dgdeg', 2)]
>>>> l.sort(key=itemgetter(3))
>>>> l
> [('wascas', 'aaa', 'fdvdfv', 1), ('rtgdsf', 'bbb', 'trfg', 1), ('addwe',
> 'ccc', 'esd', 1), ('xasd', 'aaa', 'wascaq', 2), ('nhy', 'bbb', 'asw', 2),
> ('zzzz', 'ccc', 'dgdeg', 2)]
>>>> l.sort(key=itemgetter(1))
>>>> l
> [('wascas', 'aaa', 'fdvdfv', 1), ('xasd', 'aaa', 'wasca    q', 2),
> ('rtgdsf', 'bbb', 'trfg', 1), ('nhy', 'bbb', '
> asw', 2), ('addwe', 'ccc', 'esd', 1), ('zzzz', 'ccc', 'dgdeg', 2)]
>>>>
>
>
> Also I notice your original list and your end result list are in the same
> order.
>
> Thanks
>
> Dayo
>

In my original example, you can shuffle the list before you sort it
and it will still work. Try it, with a quick "from random import
shuffle; shuffle(l)".

Also, notice that you want to sort by your primary order *last*. I
sorted by last name first, then sorted by id second, which means the
final list's primary order is by id, and secondary order by last name.
So the sorting goes in reverse. In your example, you sort by id first,
then last name. So your final list's primary order is by last name.

Hugo


More information about the Tutor mailing list