Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to sort only few values inside a list in Python

Suppose

A = [9, 5, 34, 33, 32, 31, 300, 30, 3, 256]

I want to sort only a particular section in a list. For example, here I want to sort only [300, 30, 3] so that overall list becomes:

A = [9, 5, 34, 33, 32, 31, 3, 30, 300, 256]

Suppose B = [300, 30, 400, 40, 500, 50, 600, 60] then after sorting it should be B = [30, 300, 40, 400, 50, 500, 60, 600].

Main idea if the leftmost digit is same 300, 30, 30 and right most digits contain only zeros then we should arrange it in increasing order.

Another example:

A = [100, 10, 1, 2000, 20, 2]

After sorting it should be A = [1, 10, 100, 2, 20, 2000]

Could anyone suggest some techniques to approach such issue. The values in my list will always be arranged in this way [200, 20, 2, 300, 30, 3, 400, 40, 4].

Code:

nums = [3, 30, 31, 32, 33, 34, 300, 256, 5, 9]
nums = sorted(nums, key=lambda x: str(x), reverse=True)
print nums
>> [9, 5, 34, 33, 32, 31, 300, 30, 3, 256]

But my final output should be [9, 5, 34, 33, 32, 31, 3, 30, 300 256].

Here is a big example:

A = [9, 5, 100, 10, 30, 3, 265, 200, 20, 2]

After sorting it should be:

A = [9, 5, 10, 100, 3, 30, 265, 2, 20, 200]
like image 917
python Avatar asked Nov 20 '15 09:11

python


People also ask

How do you sort a list of few elements in Python?

sort() is one of Python's list methods for sorting and changing a list. It sorts list elements in either ascending or descending order. sort() accepts two optional parameters. reverse is the first optional parameter.

How do you sort half of a list in Python?

Algorithm : Sort the given array. Run a loop up to half the length of the array and print the elements of the sorted array. Run a loop from the last index of the array to the middle of the array and print the elements in reverse order.

How do you sort a list inside a list in Python?

You can sort a list in Python using the sort() method. The method accepts two optional arguments: reverse : which sorts the list in the reverse order (descending) if True or in the regular order (ascending) if False (which it is by default)

How do you sort multiple elements in a list Python?

To sort a list of tuples by multiple elements in Python: Pass the list to the sorted() function. Use the key argument to select the elements at the specific indices in each tuple. The sorted() function will sort the list of tuples by the specified elements.


2 Answers

Since each expected sequence is contains the numbers which are a common coefficient of power of then, You can use a scientific_notation function which returns the common coefficient.Then you can categorize your numbers based on this function and concatenate them.

>>> from operator import itemgetter
>>> from itertools import chain,groupby

>>> def scientific_notation(number):
...     while number%10 == 0:
...         number = number/10
...     return number

>>> A = [9, 5, 34, 33, 32, 31, 300, 30, 3, 256]
>>> G=[list(g) for _,g in groupby(A,key=scientific_notation)] 
>>> list(chain.from_iterable(sorted(sub) if len(sub)>1 else sub for sub in G))
[9, 5, 34, 33, 32, 31, 3, 30, 300, 256]

Note that since we are categorizing the numbers based on coefficient of power of then if the length of a sub-list be more than 1 means that it's a sequence of expected numbers which need to be sort.So instead of checking the length of each sequence you can simply apply the sort on all the generators in group by:

>>> list(chain.from_iterable(sorted(g) for _,g in groupby(A,key=scientific_notation)))
[9, 5, 34, 33, 32, 31, 3, 30, 300, 256]
like image 178
Mazdak Avatar answered Oct 08 '22 23:10

Mazdak


Really got twisted with this one , still don't know if it would work for all cases.

nums = [3, 30, 31, 32, 33, 34, 300, 256, 5, 9]
map(lambda x: x[1],sorted(zip(range(0,len(nums)),sorted(nums, key=lambda x: str(x), reverse=True)), key=lambda x: str(x[1]) if not str(x[1]).endswith('0') else str(str(x[1]-1)[0])+str(x[0]), reverse=True))

O/P : [9, 5, 34, 33, 32, 31, 3, 30, 300, 256]

Now I guess it would work with everything:

Earlier one wouldn't work with this nums = [30, 3, 31, 32, 33, 34, 330, 256, 5, 9]

nums = [30, 3, 31, 32, 33, 34, 330, 256, 5, 9]
map(lambda x: x[1],sorted(zip(range(0,len(nums)),sorted(nums, key=lambda x: str(x), reverse=True)), key=lambda x: str(x[1]) if not str(x[1]).endswith('0') else str(int(str(x[1]).strip("0"))-1)+str(x[0]), reverse=True))

O/P: [9, 5, 34, 33, 330, 32, 31, 3, 30, 256]

Here what I have done is taking your sorted list function , applied a zip after enumerating it So I would get [(0, 9), (1, 5), (2, 34), (3, 33), (4, 32), (5, 31), (6, 300), (7, 30), (8, 3), (9, 256)] for your input then if an element endswith a zero I would remove trailing zeros and subtract 1 and then convert it to string and append sorted index to the string which would give me a sorted list as per your case.

For e.g

Step one : zip index [(0, 9), (1, 5), (2, 34), (3, 33), (4, 32), (5, 31), (6, 300), (7, 30), (8, 3), (9, 256)]

Step two : strip trailing zeros [(0, 9), (1, 5), (2, 34), (3, 33), (4, 32), (5, 31), (6, 3), (7, 3), (8, 3), (9, 256)]

Step three : subtract 1 from those elements which had trailing zeros [(0, 9), (1, 5), (2, 34), (3, 33), (4, 32), (5, 31),(6, 3-1), (7, 3-1) (8, 3), (9, 256)]

Step four : if had trailing zeros sort them by reversed index ie first value in tuple [(0, 9), (1, 5), (2, 34), (3, 33), (4, 32), (5, 31), (8, 3), (7, 2), (6, 2), (9, 256)]

Step five : get sorted [9, 5, 34, 33, 32, 31, 3, 30, 300, 256]

OR :

More correct and Simpler solution :

sorted(map(lambda x : str(x),[9, 5, 100, 10, 30, 3, 265, 200, 20, 2]),key=lambda x : x.strip("0")+x.rjust(len(x)+(len(x)-len(x.strip("0"))),'0'),reverse=True)
like image 43
Akshay Hazari Avatar answered Oct 09 '22 00:10

Akshay Hazari