I have a list of actions from a database. This is copied into a deque since I want to deal with it in order, popping stuff off the left as I go.
So I have something like actions = deque(actions) which is fine.
Each action item is a list from the psycopg module using the DictCursor. Each list has the item ‘phase’.
So things go in phases. Some actions are in phase ‘a’, some in phase ‘b’, etc. Not the best way to store the data but that’s what I was given.
So to make my life easier I want to split the deque into several deques by phase.
So if actions[0][‘phase’] == ‘a’ then this goes in a list containing only items from phase a, and so on with, b, etc.
I could do this with a bunch of ifs and appending but that seems like a lot of effort. I think the answer might be filter(), but I’m not so sure how to use it.
Random stuff to note:
- Each item is in order, the order needs preserving within each deque.
- The phases are known and sequential. For example, if phase c doesn’t exist, we know that phase d doesn’t exist. There are a finite number of phases, something like 5 if I recall.
Clarification attempt:
I have a deque, actions. something like:
actions = [
['phase': 'a', 'something_else': 'x'],
['phase': 'a', 'something_else': 'y'],
['phase': 'b', 'something_else': 'x']
]
Want to end up with (something like):
a = [
['phase': 'a', 'something_else': 'x'],
['phase': 'a', 'something_else': 'y']
]
b = [
['phase': 'b', 'something_else': 'x']
]
With the minimal amount of code, and something that works for any number of phases/items in phases/etc.
First define a key function that returns the phase when given an action, e.g.
Now first sort by
key— this does not rearrange order more than necessary, i.e. order is conserved for each phase (it’s “stable“) — then usegroupbyfromitertoolslike this:As you see I’ve reversed the lists. This is so you can just efficiently pop off the end of the lists instead of using popleft on a deque. If you prefer, turn them into a deque instead of reversing. Now use like this: