简体   繁体   中英

Sort a list with string of integers separated by space

Python: I have a 1-D list that has the following structure(each entry is a string of integers separated by space):

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",
        ]

But I am looking for a sorted order with respect to each integer in the both row as well as column order, ie, the expected output is

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",
]

I have tried using the sort() as well as sorted() mechanism, but nothing seems to work sort_len = list1.sort(key = int) --> This is throwing value error as each list is a string of letters seperated.

I want to sort this list by row value, ie, the first integer in a row (and in case of same row value, ie, same first integer then go to the next column)

The trick is turn each string to integer tuple.

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

You can sort by minimum of each row

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

You can use the sorted function and also make use of the key parameter in it to sort the values based on your cutomised way.I have written the code for this.Have a look at this:

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)

What you can do first is separate each string element into a list of ints using

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

and then sort the list by each index of the values going from last to first. Assuming that the length can at most be 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))

and then your vals will be sorted. for eg, if you run your example vars through this, the output will be

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

After that, just convert it back to a string using

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

Full program as a function:

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

Separated sorting of cols and rows. No for loop is bit more pythonic

Code:

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

Output:

Sorted columns:

['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']

Sorted rows:

['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']

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM