More information about the Underscore mailing list

[_] Python Question

Matt Hamilton matth at netsight.co.uk
Thu Dec 17 16:14:39 GMT 2009

On 17 Dec 2009, at 15:51, Andy Gale wrote:

> Hi _,
>
> I know there's a few Python goons on here so... is there a better way
> of doing this in Python?
>
> attributes = {}
>
> attribute_data = mark.fetchall()
>
> for i in attribute_data:
>
>       if i[1] in attributes:
>               attributes[i[1]].append(i[0])
>       else:
>               attributes[i[1]] = [i[0]]
>
> Given my experience with Python so far, there is probably some epic
> shortcut for doing this.

well firstly you can unpack values on the loop if you know the size of  
the tuples in attribute_data are all the same size, eg:

for foo,bar in attribute_data:
     if bar in attributes:
         attributes[bar].append(foo)
     else:
         attributes[bar] = [foo,]

Which makes it a bit more legible, if you replace foo and bar with  
something more meaningful ;)

If the case is likely that bar will be in attributes you could do do  
the 'do it, then ask forgiveness' route:

for foo,bar in attribute_data:
     try:
         attributes[bar].append(foo)
     except KeyError:
         attributes[bar] = [foo,]

Or another neater pattern is this:

for foo,bar in attribute_data:
     attributes[bar] = attributes.get(bar, []) + [foo,]

or back in your original variable names:

for i in attribute_data:
     attributes[i[1]] = attributes.get(i[1], []) + [i[0],]

Calling attributes.get(bar) on a dict as opposed to attributes[bar]  
means you can pass in a default value to be returned if the key does  
not exist. In this case we return an empty list which we can append to  
the same as a non-empty list.

-Matt

-- 
Matt Hamilton                                       matth at netsight.co.uk
Netsight Internet Solutions, Ltd.           Understand. Develop. Deliver
http://www.netsight.co.uk                             +44 (0)117 9090901
Web Design | Zope/Plone Development & Consulting | Co-location | Hosting