Currently, I have a list of lists called result which will contain values like this, for example:
result[1] = [John, 0.32]
result[2] = [Mikey, 1.90]
result[3] = [Sarah, 1.31]
result[4] = [Nancy, 0.49]
result[5] = [Billy, 0.13]
I want to however, sort this in descending order by the number which is held in the index space [1]. So the system will return the values in that order. Would I just have to use the sorted() function and call up the index where the value is held? I do not need to resort the list is it is necessary, i will just need to output the values in descending order.
How would I go about doing this exactly?
Use the key parameter in the sorted function.
sorted(result, key = lambda x:x[1], reverse = True)
The reverse = True makes sure that the items are sorted in the descending order. The important thing to be noted here is the key parameter.
key = lambda x:x[1]
We pass a lambda function to the key parameter, which accepts one parameter. sorted picks each element from result and pass that to the key function. In our case it is the tuples. The key function returns the second item in the tuples. So, the second item in the tuple will be used as the value of the tuple itself, while sorting. It means that when we comapre [John, 0.32] and [Mikey, 1.90], we will be actually comparing 0.32 and 1.90 only.
sorted doesn't change the actual list, but creates a new sorted list. But, if you want to sort the list itself, then you can use list.sort method, like this
result.sort(key = lambda x:x[1], reverse = True)
You can do that using sorted:
new_list = sorted(old_list, key=lambda x: x[1], reverse=True)
or using sort:
old_list.sort(key=lambda x: x[1], reverse=True)
Related
Hi all I have a list of tuple like this:
L = [(el,3,1),(el2,2,3),(el3,3,2),(el4,2,4),(el5,1,3)]
and I would like to order it like this:
L_ordered = [(el5,1,3),(el2,2,3),(el4,2,4),(el,3,1),(el3,3,2)]
I am ordering first with respect to second number and then with respect to the third number but maintaining the order with respect to the second one.
Someone know how to do that in python?
Use the key argument of the sort() or sorted() function; have it return a tuple of the fields that should be considered, in the order they should be considered:
L = [(el,3,1), (el2,2,3), (el3,3,2), (el4,2,4), (el5,1,3)]
L_ordered = sorted(L, key=lambda item: (item[1], item[2]))
I've used the following approach many times to generate a list of tuples from the contents of a dictionary:
dispositions = list(dispositions.items())
In this case, the keys are different types of ways a patient can leave the emergency department, and the values are counts of those types. Now, I wanted to sort this data based on the second item in each of the tuples, so I tried this:
dispositions = list(dispositions.items()).sort(key=lambda x: x[1])
To my surprise, when I ran the code, I found that dispositions had been set to None. I tried breaking it into two parts, as follows:
dispositions = list(dispositions.items())
dispositions.sort(key=lambda x: x[1])
This works! I got my list of sorted tuples. So, I've already solved my problem, but I want to know why the first option didn't work so that I can be a better person (better programmers are better people). Can anyone help me out here?
list.sort does not return anything. So this:
dispositions = list(dispositions.items()).sort(key=lambda x: x[1])
sets dispositions to None.
sorted on the other hand returns a new list. So you would use:
dispositions = sorted(dispositions.items(), key=lambda x: x[1])
Which will set dispositions to a sorted list of tuples.
The sort function doesn't work like you might think. It does not return a sorted list, it directly modifies the list so it's sorted.
For instance, say you have this code:
a = [0, 2, 1]
a.sort()
a will now be changed [0, 1, 2]. Had I used a = a.sort() rather than just a.sort(), it would have been set to None.
This:
dispositions = list(dispositions.items()).sort(key=lambda x: x[1])
functions the same as this:
dispositions = list(dispositions.items())
dispositions = dispositions.sort(key=lambda x: x[1])
Which sets dispositions to the returned value from sort, which is None.
On the other hand, this:
dispositions = list(dispositions.items())
dispositions.sort(key=lambda x: x[1])
is not setting dispositions to the value of sort, it's simply calling the sort function on dispositions, which causes the list to be sorted as intended.
I have a list of strings which i want to sort according to number of dots(.) in the given string and if the number of dots in those strings is equal i want them to be sorted by their length.(Both in descending order should not be a problem anyway)
The first part could be implemented easily
given_list.sort(key=dots,reverse=True)
dots function is implemented and it works fine.
This is where i am stuck as I am unable to sort the already sorted list according to their lengths if the number of dots is equal.
Which leads me to think i should somehow customize the key parameter using lambda, but it does not really work as it should , but it does in the case of nested lists or dictionaries .
how do i get this done?
You can pass in a custom lambda function to the sorted method as the sorting key.
In this case, I use a lambda x: (x.count("."), len(x)), which will create a composite key of count and length, and sort accordingly:
>>> given_list = ["e.x.a", "m.p.l.e", "ex.am.ple"]
>>> sorted(given_list, key=lambda x: (x.count("."), len(x)))
['e.x.a', 'ex.am.ple', 'm.p.l.e']
>>> sorted(given_list, key=lambda x: (x.count("."), len(x)), reverse=True)
['m.p.l.e', 'ex.am.ple', 'e.x.a']
Since you are using .sort, you can do the same here as well to sort the list in-place:
>>> given_list = ["e.x.a", "m.p.l.e", "ex.am.ple"]
>>> given_list.sort(key=lambda x: (x.count("."), len(x)), reverse=True)
>>> given_list
['m.p.l.e', 'ex.am.ple', 'e.x.a']
I have a dictionary of objects where the key is a simple string, and the value is a data object with a few attributes. I'd like to sort my dictionary based on an attribute in the values of the dictionary. i have used this to sort based on the dictionaries values
sorted = dict.values()
sorted.sort(key = operator.attrgetter('total'), reverse=True)
This yields a sorted list of values (which is expected) and I lose my original keys from the dictionary (naturally). I would like to sort both the keys and values together... how can I achieve this? Any help would be greatly appreciated?
Use .items() (or its iterator version iteritems) instead of .values() to get a list of (key, value) tuples.
items = sorted(dct.iteritems(), key=lambda x: x[1].total, reverse=True)
You'll want to use .items() rather than .values(), for example:
def keyFromItem(func):
return lambda item: func(*item)
sorted(
dict.items(),
key=keyFromItem( lambda k,v: (v['total'], k) )
)
The above will sort first based on total, and for items with equal total, will sort them alphabetically by key. It will return items as (key,value) pairs, which you could just do [x[1] for x in sorted(...)] to get the values.
Use items instead of values - and a just use a lambda to fecth the sorting key itself, since there won't be a ready made operator for it:
sorted = dict.items()
sorted.sort(key = lambda item: item[1].total, reverse=True)
I have a dictionary that looks like this:
{'key_info': (rank, raw_data1, raw_data2),
'key_info2': ...}
Basically I need back a list of the keys in sorted order, that is sorted based on the rank field in the tuple.
My code looks something like this right now (diffs is the name of the dict above):
def _sortRanked(self):
print(type(self.diffs))
return sorted(self.diffs.keys(), key=lambda x: x[1], reverse=True)
that right now returns this when I run it:
return sorted(self.diffs.keys(), key=lambda x: x[1], reverse=True)
IndexError: string index out of range
keys() only gives you keys, not values, so you have to use the keys to retrieve values from the dict if you want to sort on them:
return sorted(self.diffs.keys(), key=lambda x: self.diffs[x], reverse=True)
Since you're sorting on rank, which is the first item in the tuple, you don't need to specify which item in the value tuple you want to sort on. But if you wanted to sort on raw_data1:
return sorted(self.diffs.keys(), key=lambda x: self.diffs[x][1], reverse=True)
You're passing the key as the argument to, uh, key.
[k for (k, v) in sorted(D.iteritems(), key=lambda x: x[1], reverse=True)]
You're attempting to sort on the keys of the dictionary, not the values. Replace your self.diffs.keys() call with self.diffs.items(), and then it should work (but do keep the lambda, or use operator.itemgetter(1). Tuples sort starting with the first element, so you don't have to worry about that.)
Just noticed that you only want the keys. With my suggestion, you'd have to wrap the sort with zip()[0] (making sure to unpack the resultant list of tuples from the sort by prefixing with * in the call to zip()).
You're close. Try this instead:
return sorted(self.diffs.keys(), key = lambda x: self.diffs[x][0], reverse = True)
You're sorting a list of keys, so you have to take that key back to the dictionary and retrieve element 1 in order to use it as a comparison value.