Yes, the order of elements in a python list is persistent.
Python provides a method called . append() that you can use to add items to the end of a given list. This method is widely used either to add a single item to the end of a list or to populate a list using a for loop.
Python sorted() FunctionThe sorted() function returns a sorted list of the specified iterable object. You can specify ascending or descending order. Strings are sorted alphabetically, and numbers are sorted numerically. Note: You cannot sort a list that contains BOTH string values AND numeric values.
You can use sorted
with the following key
:
sorted(l, key = lambda s: (s!='p', s=='q', s))
['p', 'p', 'a', 'b', 'c', 'd', 'f', 'g', 'n', 't', 'z', 'q', 'q']
Explanation
To get a better idea of how this is working, the following list comprehension aims to replicate what is being returned from the lambda
function defined in the key
argument prior to making comparisons:
t = [(s!='p', s=='q', s) for s in pl]
print(t)
[(True, False, 'f'),
(True, False, 'g'),
(False, False, 'p'),
(True, False, 'a'),
(False, False, 'p'),
(True, False, 'c'),
(True, False, 'b'),
(True, True, 'q'),
(True, False, 'z'),
(True, False, 'n'),
(True, False, 'd'),
(True, False, 't'),
(True, True, 'q')]
This will then be the key
to be used to sort the items in the list, as mentioned in the documentation:
The value of the key parameter should be a function that takes a single argument and returns a key to use for sorting purposes.
So taking into account that False = 0
and True = 1
, when this list of tuples is sorted the result will be the following:
sorted(t)
[(False, False, 'p'),
(False, False, 'p'),
(True, False, 'a'),
(True, False, 'b'),
(True, False, 'c'),
(True, False, 'd'),
(True, False, 'f'),
(True, False, 'g'),
(True, False, 'n'),
(True, False, 't'),
(True, False, 'z'),
(True, True, 'q'),
(True, True, 'q')]
One idea is to use a priority dictionary with a custom function. This is naturally extendable should you wish to include additional criteria.
L = ['f','g','p','a','p','c','b','q','z','n','d','t','q']
def sort_func(x):
priority = {'p': 0, 'q': 2}
return priority.get(x, 1), x
res = sorted(L, key=sort_func)
print(res)
['p', 'p', 'a', 'b', 'c', 'd', 'f', 'g', 'n', 't', 'z', 'q', 'q']
Use the key
parameter in sorted:
l = ['f','g','p','a','p','c','b','q','z','n','d','t','q']
def key(c):
if c == 'q':
return (2, c)
elif c == 'p':
return (0, c)
return (1, c)
result = sorted(l, key=key)
print(result)
Output
['p', 'p', 'a', 'b', 'c', 'd', 'f', 'g', 'n', 't', 'z', 'q', 'q']
Just define an appropriate key function:
>>> def _key(x):
... if x == 'p':
... return -1
... elif x == 'q':
... return float('inf')
... else:
... return ord(x)
...
>>> l = ['f','g','p','a','p','c','b','q','z','n','d','t','q']
>>> sorted(l, key=_key)
['p', 'p', 'a', 'b', 'c', 'd', 'f', 'g', 'n', 't', 'z', 'q', 'q']
Note, every character is mapped to an integer >= 0, so we can just rely on ord
, and since -1
will always be less than anything returned by ord
, we can use that for p, and for q, we can use infinity, so it will be alway greater than something returned by ord
.
You can find all p
and q
elements, filter the original list, and then sort:
l = ['f','g','p','a','p','c','b','q','z','n','d','t','q']
_ps, _qs = [i for i in l if i == 'p'], [i for i in l if i == 'q']
new_l = _ps+sorted(filter(lambda x:x not in {'q', 'p'}, l))+_qs
Output:
['p', 'p', 'a', 'b', 'c', 'd', 'f', 'g', 'n', 't', 'z', 'q', 'q']
You could also store you front, middle and ends in a collections.defaultdict()
, then just add all three lists at the end:
from collections import defaultdict
l = ["f", "g", "p", "a", "p", "c", "b", "q", "z", "n", "d", "t", "q"]
keys = {"p": "front", "q": "end"}
d = defaultdict(list)
for item in l:
d[keys.get(item, "middle")].append(item)
print(d["front"] + sorted(d["middle"]) + d["end"])
# ['p', 'p', 'a', 'b', 'c', 'd', 'f', 'g', 'n', 't', 'z', 'q', 'q']
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With