[Tutor] Flatten a list in tuples and remove doubles

Francesco Loffredo fal at libero.it
Sat Jul 28 18:29:20 CEST 2012


Il 28/07/2012 17:12, Francesco Loffredo ha scritto:
> Il 19/07/2012 19:33, PyProg PyProg ha scritto:
>> Hi all,
>>
>> I would get a new list as:
>>
>> [(0, '3eA', 'Dupont', 'Juliette', '11.0/10.0', '4.0/5.0', '17.5/30.0',
>> '3.0/5.0', '4.5/10.0', '35.5/60.0'), (1, '3eA', 'Pop', 'Iggy',
>> '12.0/10.0', '3.5/5.0', '11.5/30.0', '4.0/5.0', '5.5/10.0',
>> '7.5/10.0', '40.5/60.0')]
>>
>> ... from this one:
>>
>> [(0, '3eA', 'Dupont', 'Juliette', 0, 11.0, 10.0), (0, '3eA', 'Dupont',
>> 'Juliette', 1, 4.0, 5.0), (0, '3eA', 'Dupont', 'Juliette', 2, 17.5,
>> 30.0), (0, '3eA', 'Dupont', 'Juliette', 3, 3.0, 5.0), (0, '3eA',
>> 'Dupont', 'Juliette', 4, 4.5, 10.0), (0, '3eA', 'Dupont', 'Juliette',
>> 5, 35.5, 60.0), (1, '3eA', 'Pop', 'Iggy', 0, 12.0, 10.0), (1, '3eA',
>> 'Pop', 'Iggy', 1, 3.5, 5.0), (1, '3eA', 'Pop', 'Iggy', 2, 11.5, 30.0),
>> (1, '3eA', 'Pop', 'Iggy', 3, 4.0, 5.0), (1, '3eA', 'Pop', 'Iggy', 4,
>> 5.5, 10.0), (1, '3eA', 'Pop', 'Iggy', 5, 40.5, 60.0)]
>>
>> How to make that ? I'm looking for but for now I can't do it.
>>
>> Thanks in advance.
>>
>> a+
>>
> I had to study carefully your present and desired lists, and I 
> understood what follows (please, next time explain !):
> - each 7-tuple in your present list is a record for some measure 
> relative to a person. Its fields are as follows:
>     - field 0: code (I think you want that in growing order)
>     - field 1: group code (could be a class or a group to which both 
> of your example persons belong)
>     - fields 2, 3: surname and name of the person
>     - field 4: progressive number of the measure (these are in order 
> already, but I think you want to enforce this) that you want to 
> exclude from the output list while keeping the order
>     - field 5, 6: numerator and denominator of a ratio that is the 
> measure. you want the ratio to be written as a single string: "%s/%s" 
> % field5, field6
>
> Taking for granted this structure and my educated guesses about what 
> you didn't tell us, here's my solution:
>
> def flatten(inlist)
>     """
>       takes PyProg PyProg's current list and returns his/her desired one,
>       given my guesses about the structure of inlist and the desired 
> result.
>     """
>     tempdict = {}
>     for item in inlist:
>         if len(item) != 7:
>             print "Item errato: \n", item
>         id = tuple(item[:4])
>         progr = item[4]
>         payload = "%s/%s" % item[5:]
>         if id in tempdict:
>            tempdict[id].extend([(progr, payload)])
>         else:
>            tempdict[id] = [(progr, payload)]
>     for item in tempdict:
>         tempdict[item].sort() # so we set payloads in progressive 
> order, if they aren't already
>     # print "Temporary Dict: ", tempdict
>     tmplist2 = []
>     for item in tempdict:
>         templist = []
>         templist.extend(item)
>         templist.extend(tempdict[item])
>         tmplist2.append(tuple(templist))
>     tmplist2.sort()# so we set IDs in order
>     # print "Temporary List: ", tmplist2
>     outlist = []
>     for item in tmplist2:
>         templist = []
>         if isinstance(item, tuple):
>            for subitem in item:
>                if isinstance(subitem, tuple):
>                   templist.append(subitem[1])
>                else:
>                   templist.append(subitem)
>            outlist.append(tuple(templist))
>         else:
>            outlist.append(item)
>     # print "\nOutput List: ", outlist
>     return outlist
>
ok, as usual when I look again at something I wrote, I found some little 
mistakes. Here's my errata corrige:

1- of course, a function definition must end with a colon...
    line 1:
def flatten(inlist):

2- sorry, English is not my first language...
    line 9:
              print "Item length wrong!\n", item

3- I didn't insert a break statement after line 9, but if inlist 
contained a wrong item it would be nice to do something more than simply 
tell the user, for example we could skip that item, or trim / pad it, or 
stop the execution, or raise an exception... I just told it to the 
unsuspecting user, and this may very probably lead to some exception in 
a later point, or (much worse) to wrong results. So:
    line 8-9:
         if len(item) != 7:
              print "Item length wrong!\n", item
              raise ValueError("item length != 7")


... now I feel better ... but I must avoid reading my function again, or 
I'll find some more bugs!

Francesco


More information about the Tutor mailing list