Jeremiah Dodds wrote: > I've been looking over some of my code, and I've found something I do that > has a bit of a smell to it. I've searched the group and docs, and haven't > found much of anything that solves this particular problem, although I may > just not be searching correctly. > > Anyhow, I find that often I'll have a list of objects of some sort that I > want to operate on. Most of the time, I'll want to operate on the entire > list, but sometimes I'll want to operate on just one element, or retrieve > just one element, and I end up with code something like the following: > > items = [Foo(), Foo(), ... Foo()] > > a_item = [x for x in items if x.bar == some_value][0] > another_item = [x for x in items if x.baz == some_other_value][0] > > This doesn't seem correct at all, looping over the entire list to create a > list of one element and then pulling that item out. Any advice?
[some/all of this may be obvious, but since you asked...] i think the most common solution (at least in my code) is to use a dict and store the data as a map from value to instance. you can still operate on all the instances via .values(), but you also have O(1) access via the key. another approach is to use a sorted list. then you can access things via the bisect module in O(log(n)) time. related to sorted lists, you may be able to reframe the algorithm as something that operates on a queue or stack (if your "some_value" is to find the "next" item according to an order that is fixed by earlier processing). in that case you want deque from collections. but when you need to access instances by more than one value (.bar and .baz) then typically that's a hard problem, and there's a trade-off somewhere. you might find writing a special container that contains two dicts is useful. if so, you might want to use weak references - see weakref module). all the above are relatively direct solutions. in my experience this kind of issue often comes from not thinking at a high enough level about the algorithm - even though my third suggestion (deque) sounds rather obscure you may find that once you look at you algorithm more carefully it can be rewritten in that way. i think i've seen this in my own code as i improve at integrating what might be more "functional" idioms into python in a "natural" (pythonic) way. andrew -- http://mail.python.org/mailman/listinfo/python-list