views:

228

answers:

1

I've been having a problem with making sorted lists from dictionaries. I have this list

list = [
    d = {'file_name':'thisfile.flt', 'item_name':'box', 'item_height':'8.7', 'item_width':'10.5', 'item_depth':'2.2', 'texture_file': 'red.jpg'},
    d = {'file_name':'thatfile.flt', 'item_name':'teapot', 'item_height':'6.0', 'item_width':'12.4', 'item_depth':'3.0' 'texture_file': 'blue.jpg'},
    etc.
]

I'm trying to loop through the list and

  • from each dictionary create a new list containing items from the dictionary. (It varies which items and how many items need to be appended to the list as the user makes that choice)
  • sort the list

When I say sort, I imagine creating a new dictionary like this

order = {
    'file_name':    0,
    'item_name':    1, 
    'item_height':  2,
    'item_width':   3,
    'item_depth':   4,
    'texture_file': 5
}

and it sorts each list by the values in the order dictionary.


During one execution of the script all the lists might look like this

['thisfile.flt', 'box', '8.7', '10.5', '2.2']
['thatfile.flt', 'teapot', '6.0', '12.4', '3.0']

on the other hand they might look like this

['thisfile.flt', 'box', '8.7', '10.5', 'red.jpg']
['thatfile.flt', 'teapot', '6.0', '12.4', 'blue.jpg']

I guess my question is how would I go about making a list from specific values from a dictionary and sorting it by the values in another dictionary which has the same keys as the first dictionary?

Appreciate any ideas/suggestions, sorry for noobish behaviour - I am still learning python/programming

+5  A: 

The first code box has invalid Python syntax (I suspect the d = parts are extraneous...?) as well as unwisely trampling on the built-in name list.

Anyway, given for example:

d = {'file_name':'thisfile.flt', 'item_name':'box', 'item_height':'8.7', 
     'item_width':'10.5', 'item_depth':'2.2', 'texture_file': 'red.jpg'}

order = {
    'file_name':    0,
    'item_name':    1, 
    'item_height':  2,
    'item_width':   3,
    'item_depth':   4,
    'texture_file': 5
}

one nifty way to get the desired result ['thisfile.flt', 'box', '8.7', '10.5', '2.2', "red.jpg'] would be:

def doit(d, order):
  return  [d[k] for k in sorted(order, key=order.get)]
Alex Martelli
ah yes, I re edited the post too many times before posting and got sloppy. thanks for the neat answer, I'd have never figured it out
@Ian, you're welcome!
Alex Martelli
That's not what I get in 2.6.2: >>> sorted((d[k] for k in order), key=order.get, reverse=True)['8.7', 'box', 'thisfile.flt', 'red.jpg', '2.2', '10.5']in 3.0, I get an error:>>> sorted((d[k] for k in order), key=order.get, reverse=TrueTraceback (most recent call last): File "<stdin>", line 1, in <module>TypeError: unorderable types: NoneType() < NoneType()
hughdbrown
I can get this result in 2.5, 2.6.2, and 3.0 with:>>> import operator>>> [d[k] for k,_ in sorted(order.items(), key=operator.itemgetter(1))]['thisfile.flt', 'box', '8.7', '10.5', '2.2', 'red.jpg']
hughdbrown
@hugh, tx for spotting the bug, I edited to fix it now -- but the code in your last snippet doesn't run (you're addressing a list with string keys, so of course it can't run).
Alex Martelli
The code (http://github.com/hughdbrown/StackOverflow/blob/90c5ae8c79791bca550f5bfcb69fca1909e1f191/1252481.py) runs in python 2.5 and 2.6.2. It does not run in 3.0. When cut and pasted into a python 3.0 session launched from the command line, it does run. Investigating...
hughdbrown
Okay, when I use proper print() statements in python 3.0, it works. So why do you say, "...the code in your last snippet doesn't run (you're addressing a list with string keys, so of course it can't run)"?
hughdbrown
@hugh, it may be an issue of line breaks -- I don't see any in a comment, the way SO formats it; it looks like you're doing [d[k] ...] immediately followed by ['thisfile.flt', ...] i.e. using a list of strings as index into the [d[k] ...] list; let's go to metaSO and lobby for a way to format code in cmts, but meanwhile if (as now seems likely) you were giving an output example you might consider omitting that, code's hell enough to read in cmts without such extra complications;-)
Alex Martelli
So it looks like you're using `k, _ in sorted(order.items(), key=operator.itemgetter(1))` where I have `k in sorted(order, key=order.get)`. Both work the same, mine is shorter, simpler, and over 20% faster by my measurements.
Alex Martelli
Yeah: the stuff at the end of the result of running the command at the python prompt. It looked good when I posted it. Yes, being able to format code in comments would make life so much simpler.
hughdbrown