When I find myself writing code in a way where I repeat the assembly and repeat the code after the loop ends, I usually take this as a sign that I am not trying out the right thing.
In this case, you repeat the list of objects. But what you really want to iterate over, I think, is a list of groups of objects. What itertools.groupby is useful for.
There is a lot going on in your code, so I'm going to use a simplified example to illustrate how you can get rid of this duplicate code. Let's say, for a (very far-fetched) example, that I have a list of things like this:
things = ["apples", "oranges", "pears", None, "potatoes", "tomatoes", None, "oatmeal", "eggs"]
This is a list of objects. On closer inspection, there are several groups of objects separated by the None symbol (note that you usually think of things as a nested list, but don't ignore this for the purposes of the example). My goal is to print each group on a separate line:
apples, oranges, pears potatoes, tomatoes oatmeal, eggs
Here is an ugly way to do this:
current_things = [] for thing in things: if thing is None: print ", ".join(current_things) current_things = [] else: current_things.append(thing) print ", ".join(current_things)
As you can see, after the loop we duplicate print . Nasty!
Here is a solution using groupby :
from itertools import groupby for key, group in groupby(things, key=lambda x: x is not None): if key: print ", ".join(group)
groupby accepts groupby ( things ) and key function. It looks at each element of the iteration and applies a key function. When the key changes the value, a new group is formed. The result is an iterator that returns pairs (key, group) .
In this case, we will use check for None as our key function. Therefore, we need if key: since there will be one-sized groups corresponding to the None elements of our list. We just skip them.
As you can see, groupby allows us to groupby over the things that we really want to groupby over: groups of objects. This is more natural for our problem, and as a result, the code is simplified. It looks like your code is very similar to the example above, except that your key function checks the various properties of the object ( obj.id < 400 ... ). I will leave the implementation details to you ...