sorting list of decimals in python - python

I have the following list that I'd like to sort:
['104.900209904', '238.501860857', '9.59893298149', '362.470027924', '419.737339973']
I used the "sorted" function to do it:
Block1_Video1 = sorted(Block1_Video1)
However, this is what I get:
['104.900209904', '238.501860857', '362.470027924', '419.737339973', '9.59893298149']
Whereas this is what I want (a list sorted numerically, taking decimal points into account):
[''9.59893298149', 104.900209904', '238.501860857', '362.470027924', '419.737339973']
How can I accomplish this?

The sorting needs to be based on the float values of the corresponding strings in the list.
Block1_Video1 = ['104.900209904', '238.501860857', '9.59893298149', '362.470027924', '419.737339973']
sorted(Block1_Video1,key=lambda x:float(x))
Or simply use
sorted(Block1_Video1, key=float)

You have to convert your strings in numbers first, this is possible with the key-Argument of the sorted function:
Block1_Video1 = sorted(Block1_Video1, key=float)
or as you assign the new list to the same variable, you can also sort in-place:
Block1_Video1.sort(key=float)

Related

How to get into details of str() and int() conversion [duplicate]

Tackling a few puzzle problems on a quiet Saturday night (wooohoo... not) and am struggling with sort(). The results aren't quite what I expect. The program iterates through every combination from 100 - 999 and checks if the product is a palindome. If it is, append to the list. I need the list sorted :D Here's my program:
list = [] #list of numbers
for x in xrange(100,1000): #loops for first value of combination
for y in xrange(x,1000): #and 2nd value
mult = x*y
reversed = str(mult)[::-1] #reverses the number
if (reversed == str(mult)):
list.append(reversed)
list.sort()
print list[:10]
which nets:
['101101', '10201', '102201', '102201', '105501', '105501', '106601', '108801',
'108801', '110011']
Clearly index 0 is larger then 1. Any idea what's going on? I have a feeling it's got something to do with trailing/leading zeroes, but I had a quick look and I can't see the problem.
Bonus points if you know where the puzzle comes from :P
You are sorting strings, not numbers. '101101' < '10201' because '1' < '2'. Change list.append(reversed) to list.append(int(reversed)) and it will work (or use a different sorting function).
Sort is doing its job. If you intended to store integers in the list, take Lukáš advice. You can also tell sort how to sort, for example by making ints:
list.sort(key=int)
the key parameter takes a function that calculates an item to take the list object's place in all comparisons. An integer will compare numerically as you expect.
(By the way, list is a really bad variable name, as you override the builtin list() type!)
Your list contains strings so it is sorting them alphabetically - try converting the list to integers and then do the sort.
You're sorting strings, not numbers. Strings compare left-to-right.
No need to convert to int. mult already is an int and as you have checked it is a palindrome it will look the same as reversed, so just:
list.append(mult)
You have your numbers stored as strings, so python is sorting them accordingly. So: '101x' comes before '102x' (the same way that 'abcd' will come before 'az').
No, it is sorting properly, just that it is sorting lexographically and you want numeric sorting... so remove the "str()"
The comparator operator is treating your input as strings instead of integers. In string comparsion 2 as the 3rd letter is lexically greater than 1.
reversed = str(mult)[::-1]

Is it possible to sort a list of strings that represents Filipino numbers

list = [dalawa, tatlo, apat, siyam, isa] and is there a way to sort this to list = [isa, dalawa, tatlo, apat, siyam]. I an new in python so I don't have any idea about this.
The python sort() method will sort a list in alphabetical order.
What you can do is assign the value of each filipino number as a dictionary, and then sort it according to value.
That should be done as so: (I'm making up the values)
list = {"dalawa":2, "tatlo":3, "apat":4, "siyam":5, "isa":1}
# look up lambda functions in order to better understand the below functionality.
# In short what this does is, return to the sorted function the values of keys in the above dictionary and telling it to sort by them and not by the actual via resetting the key parameter to the lambda function.
result = sorted(list, key=lambda x:list[x[0]])

numpy.unique gives wrong output for list of sets

I have a list of sets given by,
sets1 = [{1},{2},{1}]
When I find the unique elements in this list using numpy's unique, I get
np.unique(sets1)
Out[18]: array([{1}, {2}, {1}], dtype=object)
As can be seen seen, the result is wrong as {1} is repeated in the output.
When I change the order in the input by making similar elements adjacent, this doesn't happen.
sets2 = [{1},{1},{2}]
np.unique(sets2)
Out[21]: array([{1}, {2}], dtype=object)
Why does this occur? Or is there something wrong in the way I have done?
What happens here is that the np.unique function is based on the np._unique1d function from NumPy (see the code here), which itself uses the .sort() method.
Now, sorting a list of sets that contain only one integer in each set will not result in a list with each set ordered by the value of the integer present in the set. So we will have (and that is not what we want):
sets = [{1},{2},{1}]
sets.sort()
print(sets)
# > [{1},{2},{1}]
# ie. the list has not been "sorted" like we want it to
Now, as you have pointed out, if the list of sets is already ordered in the way you want, np.unique will work (since you would have sorted the list beforehand).
One specific solution (though, please be aware that it will only work for a list of sets that each contain a single integer) would then be:
np.unique(sorted(sets, key=lambda x: next(iter(x))))
That is because set is unhashable type
{1} is {1} # will give False
you can use python collections.Counter if you can can convert the set to tuple like below
from collections import Counter
sets1 = [{1},{2},{1}]
Counter([tuple(a) for a in sets1])

Python Sorting 2D List with custom Key

So I have a 2D list and want to sort it using a second file of keys. Does anyone know how I would go about doing that?
Heres an example input:
And here is an example input file:
first_nm,last_nm,gender,cwid,cred_hrs,qual_pts,gpa
John,Roe,M,44444444,40,150,3.75
Jane,Roe,F,66666666,100,260,2.6
John,Doe,M,22222222,50,140,2.8
Jane,Doe,F,88888888,80,280,3.5
Penny,Lowe,F,55555555,40,140,3.5
Lenny,Lowe,M,11111111,100,280,2.8
Denny,Lowe,M,99999999,80,260,3.25
Benny,Lowe,M,77777777,120,90,0.75
Jenny,Lowe,F,33333333,50,90,1.8
Zoe,Coe,F,0,50,130,2.6
Here are the keys to sort it(there could be more or less, depending on how you want to sort it)
gender,ascend,string
gpa,descend,float
last_nm,ascend,string
And here would be the output for that input and keys:
first_nm,last_nm,gender,cwid,cred_hrs,qual_pts,gpa
Jane,Doe,F,88888888,80,280,3.5
Penny,Lowe,F,55555555,40,140,3.5
Zoe,Coe,F,00000000,50,130,2.6
Jane,Roe,F,66666666,100,260,2.6
Jenny,Lowe,F,33333333,50,90,1.8
John,Roe,M,44444444,40,150,3.75
Denny,Lowe,M,99999999,80,260,3.25
John,Doe,M,22222222,50,140,2.8
Lenny,Lowe,M,11111111,100,280,2.8
Benny,Lowe,M,77777777,120,90,0.75
I was thinking of just using the built in sort() but was not sure if I would be able to use it if I am sorting 3 different times. I think I would have to sort backwards? (last_nm, then gpa, then gender)
You can return a tuple from your key function to create complex sorts. And as a quick trick, multiply numeric values by -1 for a reverse sort. Your example would look something like this:
lists.sort(key = lambda x: (x[2], x[6] * -1, x[1]))
The list sort() method takes a boolean parameter reverse, but it applies to the whole key; you can't say that you want some parts of the key to use ascending sort and others to use descending. Sadly, there isn't a simple way to extend g.d.d.c's trick of multiplying by -1 to non-numeric data.
So if you need to handle arbitrary combinations of ascending and descending then yes, you will have to sort multiple times, working backwards over your list of keys, like you mention in your question. The built-in Python sorting algorithm, timsort, is a stable sort, which means each time you sort your 2D list with a different key the previous sort results won't get scrambled.

Python .sort() not working as expected

Tackling a few puzzle problems on a quiet Saturday night (wooohoo... not) and am struggling with sort(). The results aren't quite what I expect. The program iterates through every combination from 100 - 999 and checks if the product is a palindome. If it is, append to the list. I need the list sorted :D Here's my program:
list = [] #list of numbers
for x in xrange(100,1000): #loops for first value of combination
for y in xrange(x,1000): #and 2nd value
mult = x*y
reversed = str(mult)[::-1] #reverses the number
if (reversed == str(mult)):
list.append(reversed)
list.sort()
print list[:10]
which nets:
['101101', '10201', '102201', '102201', '105501', '105501', '106601', '108801',
'108801', '110011']
Clearly index 0 is larger then 1. Any idea what's going on? I have a feeling it's got something to do with trailing/leading zeroes, but I had a quick look and I can't see the problem.
Bonus points if you know where the puzzle comes from :P
You are sorting strings, not numbers. '101101' < '10201' because '1' < '2'. Change list.append(reversed) to list.append(int(reversed)) and it will work (or use a different sorting function).
Sort is doing its job. If you intended to store integers in the list, take Lukáš advice. You can also tell sort how to sort, for example by making ints:
list.sort(key=int)
the key parameter takes a function that calculates an item to take the list object's place in all comparisons. An integer will compare numerically as you expect.
(By the way, list is a really bad variable name, as you override the builtin list() type!)
Your list contains strings so it is sorting them alphabetically - try converting the list to integers and then do the sort.
You're sorting strings, not numbers. Strings compare left-to-right.
No need to convert to int. mult already is an int and as you have checked it is a palindrome it will look the same as reversed, so just:
list.append(mult)
You have your numbers stored as strings, so python is sorting them accordingly. So: '101x' comes before '102x' (the same way that 'abcd' will come before 'az').
No, it is sorting properly, just that it is sorting lexographically and you want numeric sorting... so remove the "str()"
The comparator operator is treating your input as strings instead of integers. In string comparsion 2 as the 3rd letter is lexically greater than 1.
reversed = str(mult)[::-1]

Categories