Notice that what you are trying to do is a reordering of your list to put the elements of predefined_list
at the end. Hence your function can be as simple as:
def sanitize(arg):
predefined_list = [1, 2]
# Note that False<True and sort algorithm is stable, so:
return sorted(arg, key=lambda x: x in predefined_list)
As an alternative to the lambda
, you can use predefined_list.__contains__
.
In fact the sorting key is False
for elements which are not in predefined_list
and True
for elements which are contained. Since False<True
the latter elements will be moved at the end of the list.
For this to work it is important to know that (at least from Python 2.2) the sort algorithm is guaranteed to be stable, i.e., it does not change the order of elements with the same key.
If you want to implement the algorithm yourself I would suggest, as @janos already did, to iterate first on the array to be sorted. This is better for performance and solves the issue of repeated elements.
A possible implementation could be:
def sanitize(arg):
predefined_list = [1,2]
pop_count = 0
for i in range(len(arg)):
if arg[i-pop_count] in predefined_list:
arg.append(arg.pop(i-pop_count))
pop_count += 1
About your code: I don't like the use of Exceptions to handle non exceptional situations... however the index
method seems to force you to use exceptions so I see no alternative. Anyway I would keep the code inside the try...except block to the minimum, because otherwise you run the risk to hide exceptions caused by some other issue.
Another point is the fact that your algorithm does not handle repeated elements in the original list. You could handle them easily, see below.
Here is a possible cleaning of your implementation:
def sanitize(lst,predefined):
"""
reorder elements of @lst by moving the elements which also
belong to @predefined at the end of the list
"""
for item in predefined:
while True:
try:
i = lst.index(item)
except ValueError:
# lst does not contain any occurence of item
break
# move the i-th element to the end of the list
lst.append(lst.pop(i))
return lst
Only now I notice that the choice of the algorithm changes the resulting list. In fact you have to decide wether the elements moved at the end must keep the original order in the list (as in my suggested implementations) or must keep the order in the list of items to be removed (as in yours).
arg
has not repeating values... \$\endgroup\$