0

I have a line of code like so:

event = [x for x in history if x.serial == serialized_event]

In all circumstances in my application, the resulting list will only ever contain a single item. But it seems to me it is going to iterate over the entire "history" list anyway looking for all possible matches.

This is unnecessary, especially since in most cases it will find what I'm looking for within the first few indices and it will effectively be the only result.

How can I make this more efficient?

9
  • 1
    is x.serial sorted?
    – hashcode55
    Commented Jul 18, 2016 at 17:32
  • 6
    sorry, didn't read the question properly... but I think that question is very close to what you want - stackoverflow.com/questions/2361426/…
    – Vince W.
    Commented Jul 18, 2016 at 17:33
  • Not inherently, but it could easily be made so. History is a Django queryset.
    – Ivan
    Commented Jul 18, 2016 at 17:34
  • 1
    What kind of data structure is history? Can you optimize that? For example dictionaries and sets have O(1) time complexity for membership checks. However if you always find the result in the first couple of indices it doesn't sound like this is a bottle neck so optimizing may end up costing more than it saves.
    – kylieCatt
    Commented Jul 18, 2016 at 17:34
  • 1
    QuerySets are lazy. More so, a search on the DB is more likely to be faster than in Python Commented Jul 18, 2016 at 17:45

2 Answers 2

2

If the one-liner is not necessary, just use a regular for loop with a break:

event = []
for x in history:
    if x.serial == serialized_event:
        event.append(x)
        break
0

And if you would like to keep a one liner, use itertools.dropwhile to filter the undesired results, and fetch only the first matching item:

from itertools import dropwhile

event = next(dropwhile(lambda x: x.serial==serialized_event, history))

Not the answer you're looking for? Browse other questions tagged or ask your own question.