As per the items in a list in ascending or descending order?

-1

I'm trying to get the numbers in a list in ascending order but the sort () method is putting the 10 and its multiples (20, 30) as being similar to itself divided by 10. For example, in the following code:

numeros = ['1', '3', '2', '20', '4', '10', '30']  
numeros.sort()  
print(numeros)  

It returns me in response:

['1', '10', '2', '20', '3', '30', '4']  

Instead of:

['1', '2', '3', '4', '10', '20', '30']  

As expected. So why does this happen and how do I get them to grow? And how would I stop in descending order?

    
asked by anonymous 17.12.2017 / 03:21

1 answer

2

Python is a dynamic language, which means that there is no limitation of the type that a function can receive as an argument. Now the function can receive a string , or it can receive an integer and, with that, it is usually done that the function can respond in an expected way to all. One implication of this, when parsed especially the sorted function, is that when you pass a list of numbers, they will be sorted incrementally, but when you pass a list of strings , it will be sorted alphabetically . You have a list of strings , so the output will be alphabetical, not numeric and thus there are two considerations to be made, which by the way are unique to each other - that is, one or the other: / p>

  • You have a list of strings that have numeric characters; you need them to remain strings because because of the semantics of your problem this will make sense and just want to sort them numerically.
  • If this is your situation then you should use the key argument of the sorted function. Through it you will indicate a callable object - it can be a function, a class, an object that implements __call__ , etc - and so the function will use it when analyzing the values in the list before ordering them. By default, this argument is None , and the list is sorted by taking the values directly; when different from% with%, the list is sorted by considering the return of the callable object passed by None to each value in the list. This object will always be memoised - applied memoization - which means that the function will be called only once for each value in the list, which does not affect performance.

    As you have a list of strings and you want to classify them as integers, just pass the class key through the argument int :

    >>> sorted(numeros, key=int)
    ['1', '2', '3', '4', '10', '20', '30']
    

    So, the list will be sorted according to the return of key for each value, but the result will remain as a list of strings . If you want to reverse sort them, just indor the argument int as true:

    >>> sorted(numeros, key=int, reverse=true)
    ['30', '20', '10', '4', '3', '2', '1']
    

    If, after sorting the list, you no longer need to work with the original list, you would prefer to use the reverse method instead of the sort function:

    numeros.sort(key=int)  # Crescente
    numeros.sort(key=int, reverse=True)  # Decrescente
    

    Because the method will only modify the list itself in memory, while the sorted function will generate a new list, consuming twice the application memory.

  • You have a list of strings that have numeric characters; it does not make sense that they are strings and semantically the values should be integers - imagine a list of ages: age is an integer value, not a string ; >

    For this situation, the recommended thing to do is to convert the values to integers and only then sort them as you wish. For this, you will necessarily have to create a new list, so there are no preferences between sorted or sorted . To avoid unnecessary memory expense, you can create a generator to convert strings to integer and sort the generator itself. The generator is running lazy, that is, it only executes its logic when needed, so you will not have to create a list of unordered integers before ordering them - though you create the temporary list and sort it by the sort will have the same result; use whatever is most convenient.

    To create the strings list generator in integer list, just use the sort function:

    numeros_inteiros = map(int, numeros)
    

    And so, sort them up or down:

    >>> sorted(numeros_inteiros)  # Crescente
    [1, 2, 3, 4, 10, 20, 30]
    
    >>> sorted(numeros_inteiros, reverse=True)  # Decrescente
    [30, 20, 10, 4, 3, 2, 1]
    

    If you prefer to create the temporary list and use the map method, it would look something like:

    numeros = [int(numero) for numero in numeros]
    numeros.sort()  # Crescente
    numeros.sort(reverse=True)  # Decrescente
    

    Note that as I commented in both situations, the first result is still a list of strings , but sorted in numerical form, while in the second the result will already be a list of integers. p>     

  • 18.12.2017 / 00:00