Сортировать список со строкой целых чисел, разделенных пробелом

Питон: У меня есть одномерный список со следующей структурой (каждая запись представляет собой строку целых чисел, разделенных пробелом):

vals = ["121",
        "121 122",
        "122",
        "122 124",
        "150",
        "171",
        "49",
        "49 122",
        "49 122" "124",
        "49 122" "516",
        "51",
        "51 122",
        "516",
        "8",
        "8 122" "516",
        "8 124",
        "8 171",
        "8 49",
        "8 49" "124",
        "8 49" "516",
        "8 51",
        "8 51" "122",
        "8 516",
        "878",
        ]

Но я ищу отсортированный порядок по отношению к каждому целому числу как в строке, так и в порядке столбца, т. е. ожидаемый результат

vals = [
    "8",
    "8 49",
    "8 49 124",
    "8 49 516",
    "8 51",
    "8 51 122",
    "49",
    "49 122",
    "49 122 124",
    "49 122 516",
    "51",
    "51 122",
    "121",
    "121 122",
    "122",
    "122 124",
    "150",
    "171",
    "516",
    "878",
]

Я пытался использовать механизм sort() и sorted(), но ничего не работает. sort_len = list1.sort(key = int) --> Это выдает ошибку значения, так как каждый список представляет собой строку букв, разделенных.

Я хочу отсортировать этот список по значению строки, т.е. первому целому числу в строке (и в случае того же значения строки, т.е. того же первого целого числа, затем перейти к следующему столбцу)

Можно предположить, что каждая строка уже отсортирована по столбцам, т. е. каждая строка находится в порядке сортировки по столбцам.

Manoj S 19.12.2020 18:44
key=lambda x: tuple(map(int, x.split())) может сработать
Bakuriu 19.12.2020 18:45

Он по-прежнему выдает ошибку: list1.sort(key = lambda x: tuple(map(int, x.split(',')))) ValueError: недопустимый литерал для int() с базой 10: '39 41 48'

Manoj S 19.12.2020 18:50

@ManojS - x.split() не x.split(',')

wwii 19.12.2020 19:00

То же самое, но другое key = lambda x: [int(n) for n in x.split()]

wwii 19.12.2020 19:02
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
1
5
333
5
Перейти к ответу Данный вопрос помечен как решенный

Ответы 5

Вы можете сортировать по минимуму каждой строки

list1.sort(key=lambda e:min([int(se) for se in e.split()]))

Большое спасибо за ваш вклад @Adithya Но, если мой текущий список выглядит так: [ 1004<br> 101<br> 10515<br> 110<br> 1146<br> 38 110<br> 38 170<br> 38 286<br> 38 39<br> 38 39 110<br> 38 39 170<br> 38 39 41<br> 38 39 41 48<br> 38 39 48<br> 38 39 48 110<br> 38 39 48 170<br> 38 41<br> 38 41 48<br> 38 48<br> 38 48 110<br> 38 48 170<br> 39<br> 8<br> ]

Manoj S 19.12.2020 19:05

Я вижу вывод с использованием предложенной сортировки как: [ 8<br> 38 39<br> 38 39 110<br> 38 39 170<br> 38 39 41<br> 38 39 41 48<br> 38 39 48< 38 39 48 110<br> 38 39 48 170<br> 38 41<br> 38 41 48<br> 38 48<br> 38 48 110<br> 38 48 170<br> 39<br> 101< br> 110<br> 1004<br> 1146<br> 10515<br> ] Начинается сбой порядка в третьем столбце

Manoj S 19.12.2020 19:07
Ответ принят как подходящий

Хитрость заключается в том, чтобы превратить каждую строку в целочисленный кортеж.

print(sorted(vals, key = lambda y: tuple(int(x) for x in y.split())))

['8', '8 49', '8 49 124', '8 49 516', '8 51', '8 51 122', '8 122 516', '8 124', '8 171', '8 516', '49', '49 122', '49 122 124', '49 122 516', '51', '51 122', '121', '121 122', '122', '122 124', '150', '171', '516', '878']

Большое спасибо за ваш вклад @Lior Cohen. Это действительно работает как шарм. Вот итоговый список: [ 38 <br> 38 39 <br> 38 39 41<br> 38 39 41 48<br> 38 39 48<br> 38 39 48 110<br> 38 39 48 170<br> 38 39 110<br> 38 39 170<br> 38 41<br> 38 41 48<br> 38 48<br> 38 48 110<br> 38 48 170<br> 38 110<br> 38 170<br> 38 286<br> 39<br> ]

Manoj S 19.12.2020 19:36

пожалуйста @ManojS. Пожалуйста, подумайте о том, чтобы проголосовать за -1, который кто-то дал, когда у вас есть на это право.

Lior Cohen 19.12.2020 21:21

Вы можете использовать функцию sorted, а также использовать ключевой параметр в ней для сортировки значений в зависимости от вашего пути. Я написал код для этого. Посмотрите на это:

lis =["121","51 122","122 123 23","2 13 4"]
newlis =[]
for i in lis:
    numbers = [int(s) for s in i.split(" ")]
    numbers = [str(s) for s in sorted(numbers)]
    newlis.append(str(" ".join(numbers)))
newlis = sorted(newlis,key = lambda x: [int(s) for s in x.split(" ")][0])
print(newlis)

Большое спасибо за ваш вклад @PILLI VINEETH. Я попробовал предложенный вами метод, но я вижу неупорядоченный список: [ 37 38 <br> 37 <br> 38 39 170 <br> 38 48 110 <br> 38 170 <br> 38 41 48 <br> > 38 39 48 <br> 38 39 41 <br> 38 48 170 <br> 38 41 <br> 38 39 <br> 38 48 <br> 38 39 48 170 <br> 38 <br> ]

Manoj S 19.12.2020 19:35

Сначала вы можете разделить каждый строковый элемент на список целых чисел, используя

[list(map(int, i.split())) for i in vals]

а затем отсортируйте список по каждому индексу значений, идущих от последнего к первому. Предполагая, что длина не может быть больше 3,

func = lambda x,p: x[len(x)-p if len(x)-p > 0 else 0]
vals = sorted(vals, key=lambda x: func(x,1))
vals = sorted(vals, key=lambda x: func(x,2))
vals = sorted(vals, key=lambda x: func(x,3))

и тогда ваши вальсы будут отсортированы. например, если вы запустите свой пример vars через это, вывод будет

[[8], [8, 49], [8, 51], [8, 124], [8, 171], [8, 516], [8, 49124], [8, 49516], [8, 51122], [8, 122516], [49], [49, 122], [49, 122124], [49, 122516], [51], [51, 122], [121], [121, 122], [122], [122, 124], [150], [171], [516], [878]]

После этого просто преобразуйте его обратно в строку, используя

vals = list(map(lambda x:" ".join([str(i) for i in x]), vals))

Полная программа как функция:

def sort_vals(vals):
    vals = [list(map(int, i.split())) for i in vals]

    func = lambda x,p: x[len(x)-p if len(x)-p > 0 else 0]
    vals = sorted(vals, key=lambda x: func(x,1))
    vals = sorted(vals, key=lambda x: func(x,2))
    vals = sorted(vals, key=lambda x: func(x,3))

    vals = list(map(lambda x:" ".join([str(i) for i in x]), vals))
    return vals

Раздельная сортировка столбцов и строк. Нет цикла for немного более pythonic

Код:

def sort_str(in_str):
    in_lst = [int(s) for s in in_str.split()]
    return ' '.join(str(i) for i in sorted(in_lst))
    
lst = ['121', '121 122', '122', '122 124', '150', '171', '49', '49 122', '49 122 124', '49 122 516', '51', '51 122', '516', '8', '8 122 516', '8 124', '8 171', '8 49', '8 49 124', '8 49 516', '8 51', '8 51 122', '8 516', '878' ]
lst = [sort_str(ele) for ele in lst]
print(lst) # Sorted columns:
lst.sort(key = lambda s : int(s.split()[0]))
print(lst) #Sorted rows

Выход:

Отсортированные столбцы:

['121', '121 122', '122', '122 124', '150', '171', '49', '49 122', '49 122 124', '49 122 516', '51', '51 122', '516', '8', '8 122 516', '8 124', '8 171', '8 49', '8 49 124', '8 49 516', '8 51', '8 51 122', '8 516', '878']

Отсортированные строки:

['8', '8 122 516', '8 124', '8 171', '8 49', '8 49 124', '8 49 516', '8 51', '8 51 122', '8 516', '49', '49 122', '49 122 124', '49 122 516', '51', '51 122', '121', '121 122', '122', '122 124', '150', '171', '516', '878']

Другие вопросы по теме