Упорядочить список по типу содержимого?
Есть список: [1, 3, 5, 'adf', 34, (1, 5, 8)]. Хочу упорядочить его по типу содержимого, чтобы сначала шли целые числа, строка и в конце кортеж.
То есть получить на выходе:
[1, 3, 5, 34, 'adf', (1, 5, 8)].
Как добиться этого?
Ответы (5 шт):
Решение "в лоб":
d = [1, 3, 5, 'adf', 34, (1, 5, 8)]
digits = []
strings = []
tuples = []
for i in d:
if isinstance(i, str): # Строка?
strings.append(i)
elif isinstance(i, tuple): # Кортеж?
tuples.append(i)
elif isinstance(i, int): # Число?
digits.append(i)
print(digits + strings + tuples)
Можно использовать сортировку со своим компаратором и для него задать возврат значений как приоритет по типу.
Пример:
TYPE_BY_PRIORITY = {
int: 0,
str: 1,
tuple: 2,
}
items = [1, 3, 5, 'adf', 34, (1, 5, 8)]
items.sort(key=lambda x: TYPE_BY_PRIORITY.get(type(x)))
print(items)
# [1, 3, 5, 34, 'adf', (1, 5, 8)]
UPD.
Чтобы сортировка без ошибок обрабатывала типы, что нет в TYPE_BY_PRIORITY, то в .get нужно возвращать значение по умолчанию:
items.sort(key=lambda x: TYPE_BY_PRIORITY.get(type(x), 99))
UPD2.
Как подсказал MaxU, можно в компараторе возвращать кортеж вида (приоритет, значение), тогда сортировка будет и по типу, и по значению (будет порядок для элементов одного типа):
items.sort(key=lambda x: (TYPE_BY_PRIORITY.get(type(x), 99), x))
Это заметно с выборкой [3, 1, 5, 'adf', 34, (1, 5, 8)]. Компаратор только с приоритетом вернет [3, 1, 5, 34, 'adf', (1, 5, 8), 2.2], а компаратор с приоритетом и значением вернет: [1, 3, 5, 34, 'adf', (1, 5, 8)]
Вот вам "грязный хак" - по стечению обстоятельств он подходит к вашему случаю:
a = [1, 3, 5, 'adf', 34, (1, 5, 8)]
b = sorted(a, key=lambda x: str(type(x)))
print(b)
Результат:
[1, 3, 5, 34, 'adf', (1, 5, 8)]
Вот решение в стиле code-golf. Переменная l это ваш список:
[x for x in l if isinstance(x,int)]+[i for i in l if isinstance(i,str)] + [j for j in l if isinstance(j,tuple)]