Форсировать элементы в начале и конце списка
Как я могу изменить этот список так, чтобы все p's
отображались в начале, q's
в конце, а значения между ними сортировались в алфавитном порядке?
l = ['f','g','p','a','p','c','b','q','z','n','d','t','q']
Поэтому я хотел бы иметь:
['p','p','a','b','c','d','f','g','n','t','z','q','q']
Ответы
Ответ 1
Вы можете использовать sorted
со следующим key
:
sorted(l, key = lambda s: (s!='p', s=='q', s))
['p', 'p', 'a', 'b', 'c', 'd', 'f', 'g', 'n', 't', 'z', 'q', 'q']
объяснение
Чтобы лучше понять, как это работает, следующее понимание списка направлено на то, чтобы повторить то, что возвращается из lambda
функции, определенной в key
аргументе, до проведения сравнений:
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')]
Это будет key
который будет использоваться для сортировки элементов в списке, как указано в документации:
Значением параметра key должна быть функция, которая принимает один аргумент и возвращает ключ для использования в целях сортировки.
Таким образом, принимая во внимание, что False = 0
и True = 1
, когда этот список кортежей отсортирован, результат будет следующим:
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')]
Ответ 2
Одна идея состоит в том, чтобы использовать словарь приоритетов с пользовательской функцией. Это естественно расширяется, если вы хотите включить дополнительные критерии.
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']
Ответ 3
Используйте key
параметр в отсортированном:
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)
Выход
['p', 'p', 'a', 'b', 'c', 'd', 'f', 'g', 'n', 't', 'z', 'q', 'q']
Ответ 4
Просто определите соответствующую ключевую функцию:
>>> 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']
Обратите внимание, что каждый символ отображается в целое число> = 0, поэтому мы можем просто положиться на ord
, и, поскольку -1
всегда будет меньше, чем что-либо, возвращаемое ord
, мы можем использовать это для p, а для q мы можем использовать бесконечность, поэтому она всегда будет больше, чем что-то, возвращаемое через ord
.
Ответ 5
Вы можете найти все элементы p
и q
, отфильтровать исходный список и затем отсортировать:
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
Выход:
['p', 'p', 'a', 'b', 'c', 'd', 'f', 'g', 'n', 't', 'z', 'q', 'q']
Ответ 6
Вы также можете сохранить свои передние, средние и конечные значения в collections.defaultdict()
, а затем просто добавить все три списка в конце:
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']
Ответ 7
Решение этого вопроса:
- Сначала найдите все элементы p и q в списке.
- Фильтруйте оригинальный список.
- Затем, наконец, отсортировать список.
list = ['f','g','p','a','p','c','b','q','z','n','d','t','q'];
noOfPs = [i for i in l if i == 'p'];
noOfQs = [i for i in l if i == 'q'];
resultList= noOfPs + sorted(filter(lambda x:x not in {'q', 'p'}, l))+ noOfQs