Say I have a sorted list of strings as in:
[\'A\', \'B\' , \'B1\', \'B11\', \'B2\', \'B21\', \'B22\', \'C\', \'C1\', \'C11\', \'C2\']
Now I wan
If you want to sort an arbitrary subset of elements while leaving other elements in place, it can be useful to design a view over the original list. The idea of a view in general is that it's like a lens over the original list, but modifying it will manipulate the underlying original list. Consider this helper class:
class SubList:
def __init__(self, items, predicate):
self.items = items
self.indexes = [i for i in range(len(items)) if predicate(items[i])]
@property
def values(self):
return [self.items[i] for i in self.indexes]
def sort(self, key):
for i, v in zip(self.indexes, sorted(self.values, key=key)):
self.items[i] = v
The constructor saves the original list in self.items
, and the original indexes in self.indexes
, as determined by predicate
. In your examples, the predicate
function can be this:
def predicate(item):
return item.startswith('B')
Then, the values
property is the lens over the original list,
returning a list of values picked from the original list by the original indexes.
Finally, the sort
function uses self.values
to sort,
and then modifies the original list.
Consider this demo with doctests:
def demo(values):
"""
>>> demo(['X', 'b3', 'a', 'b1', 'b2'])
['X', 'b1', 'a', 'b2', 'b3']
"""
def predicate(item):
return item.startswith('b')
sub = SubList(values, predicate)
def key(item):
return int(item[1:])
sub.sort(key)
return values
Notice how SubList
is used only as a tool through which to manipulate the input values
. After the sub.sort
call, values
is modified, with elements to sort selected by the predicate
function, and sorted according to the key
function, and all other elements never moved.
Using this SubList
helper with appropriate predicate
and key
functions,
you can sort arbitrary selection of elements of a list.