Упорядочить список по типу содержимого?

Есть список: [1, 3, 5, 'adf', 34, (1, 5, 8)]. Хочу упорядочить его по типу содержимого, чтобы сначала шли целые числа, строка и в конце кортеж. То есть получить на выходе: [1, 3, 5, 34, 'adf', (1, 5, 8)].

Как добиться этого?


Ответы (5 шт):

Автор решения: Alexander Chernin

Решение "в лоб":

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)
→ Ссылка
Автор решения: gil9red

Можно использовать сортировку со своим компаратором и для него задать возврат значений как приоритет по типу.

Пример:

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)]

→ Ссылка
Автор решения: strawdog

Вот вам "грязный хак" - по стечению обстоятельств он подходит к вашему случаю:

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)]
→ Ссылка
Автор решения: Victor VosMottor thanks Monica

Вот решение в стиле 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)]
→ Ссылка