Say you have a dictionary:
a={'20101216':5,'20100216':1,'20111226':2,'20131216':5}
Two keys have the same value. How would I go about printing the the maximum key date (which is a string) and value? Like:
5 at 12/16/2013
I tried to for loop the key and the values and print the max key and max value, but it's not working out.
edit: I originally started out trying to convert an array of string dates to date objects. But it fails [b]
b=['20101216','20100216','20111226','20131216']
c=[5,1,2,5]
z=[]
for strDate in b:
g=[datetime.datetime.strptime(strDate, '%Y%m%d')]
if g not in z:
z.append(g)
Then from there if it worked I have would of done another for loop on my new array [z] to format each date element properly (m/d/y). Following that I would have zipped both arrays into a dictionary.
Like:
d = dict(zip(z,c))
Which would have resulted in
d={12/16/2010:5,02/16/2010:1,12/26/2011:2,12/16/2013:5}
Finally I would have attempted to find max date key and max value. And printed it like so:
5 at 12/16/2013
But because of the failure converting array b, I was thinking maybe working with a dictionary from the start might yield better results.
TL;DR:
max(a.items(), key = lambda x: (x[1], x[0]))
Basically, the problem is that you cant access dict's values directly and you still need to sort your data counting it. So, dict.items() gives you a list of tuples, i.e.
a.items()
[('20101216', 5), ('20131216', 5), ('20111226', 2), ('20100216', 1)]
Then all you need is to get maximum value of this list. The simple solution for getting maximum value is max func. As your problem is slightly complicated, you should leverage max key argument (take a look at doc) and use "compound" sorting key. In such situation the lambda function is a solution. You can express pretty any thing that you need to sort. So, sorting by 2 values inside tuple with corresponding priority should be
max(l, key = lambda x: (x[1], x[0])) # where l is iterable with tuples
Related
I have a list in python that looks like below
a=[['David','McConor','123000','900']
['Timothy','Gerrard','123001','901']]
I desire to sort the list above using the last entry of each sublist as the key. I have succesfully sorted the list lexicographically using the a.sort()
function. Now i want to sort the list and print each sublist such that the list with '901' comes first is my problem.
What I tried
##defining what mykey is where am stuck
mykey=
##the sort function has overloads for key
a.sort(key=mykey,reverse=True)
Thanks for your contribution.
You can use an alternative way
sorted(a, key = lambda x: (x[-1]), reverse=True)
key expects a function, you can create a simple lambda function to check for the last item:
a.sort(key=lambda x: x[-1],reverse=True)
I need to output data in a file in the following format: year-month,val. it should be sorted on year-month
for example:
2016-1,5
2016-7,1
2016-9,3
2016-11,4
2016-12,2
But, I am getting:
2016-1,5
2016-11,4
2016-12,2
2016-7,1
2016-9,3
the code is as follows:
for k,v in sorted(dictD.items()):
drow = [k,v]
writer.writerow(drow)
How to get the desired output?
Split the date at the hyphen and convert it to a tuple of numbers rather than strings.
for row in sorted(dictD.items(), key = lambda(x): map(int, x[0].split('-'))):
writer.writerow(row)
x is the (key, value) tuple returned by items(), so x[0] is the key, which is a date like '2016-1'. split splits this into the tuple ('2016', '1'), and map(int) converts that to a sequence of integers (2016, 1). Using this as the sort key will order them numerically instead of lexicographically.
Well, it's not a direct code, but I couldn't make it more simple so you may try to change the format of the month like this:
dictD = {'2016-1':5, '2017-7':1,'2016-9':3, '2016-11':4, '2016-12':2}
formatedKey = [list(dictD)[i].split('-')[0]+'-'+'{:02d}'.format(int(list(dictD)[i].split('-')[1])) \
for i in range(len(list(dictD)))]
dictD2 = dict(zip(formatedKey, list(dictD.values())))
for k,v in sorted(dictD2.items()):
drow = [k,v]
print(drow)
I didn't use the writer, but I hope this helps.
Assuming your dictionary is keyed by the YYYY-MM string and the value is the number after the comma, you can add a key argument to your sorted() call.
The key func could be:
lambda item: item[0][:5] + ('0' if len(item[0]) < 7 else '') + item[0][5:]
So your sorted call goes from:
sorted(dictD.items())
to:
sorted(dictD.items(), key=lambda item: <the rest from above>)
This leaves sorting by strings, but by adding the leading zero to the one-digit month, things come out as you want.
As a side note, you can pass a named function in as the key. You're not limited to using a lambda call.
When you pass things into sorted() without specifying a sorting algorithm, a default sort order is used. Dicts are sorted by keys (as strings), and tuples are sorted by tuple elements, starting with the first. For you, your .items() call produces a list of tuples (or at least close enough), with the key as the first element of the tuple, so the tuples get sorted by the dict keys as strings, ignoring any potential numeric value. By padding the leading zero to the one-digit months, the dates can be properly sorted as strings. The lambda call does just that -- it pads that extra '0' when necessary to allow the sorting to occur with the desired results.
Okay so I'm trying to sort a dictionary of key values pairs in a dictionary. The keys are words and values are decimal values. I'm trying to get a list of sorted keys based on the values. right now I have:
sortedList = sorted(wordSimDic, key=wordSimDic.get,reverse=True)
This works. However, I would like to be able to do one thing further. If the values of the keys match I would like them to be sorted in the outputlist by the key in alphabetical order.
For example
Input:
{'c':1,'a':1,'d':3}
Output:
[a,c,d]
right now my output is:
[c,a,d]
Do you have suggestion.Thanks so much!
In general, to 'sort by X then Y' in Python, you want a key function that produces an (X, Y) tuple (or other sequence, but tuples are simplest and cleanest really). Thus:
sorted(wordSimDic, key=lambda k: (wordSimDic.get(k), k), reverse=True)
I have a list of tuples:
lst = [('Q4-2005', 327.93), ('Q1-2005', 133.05), ('Q3-2005', 500.95), ('Q2-2005', 254.22)]
I want to sort this list by the first element of each tuple. Thus my resulting, sorted list should look like:
[('Q1-2005', 133.05), ('Q2-2005', 254.22), ('Q3-2005', 500.95), ('Q4-2005', 327.93)]
I tried doing this using sorting() and lambda, but the resulting list is not sorted. Im thinking its because my 'dates' are actually strings:
sorted(lst, key = lambda x: x[0])
So i guess I have 2 questions..
First, How do I sort the list of tuples so that they are in chronological order?
Second, what is the best way to make python realize that 'Q1-2005' is a date? Eventually I want to plot this data where x-axis is the 'date' and y-axis is the number associated with each date?
You said that you want Python to interpret Q1-2005 as a date. If you convert the list to such a format, then sorting becomes trivial, and plotting will also be easier. Here's one way to do it using datetime.date (it encodes the quarters as a date representing the first date of the quarter).
from datetime import date
# date() takes in year, month, day args
date_lst = [(date(int(q[3:]), 3 * int(q[1]) - 2, 1), v)
for q, v in lst]
This will result in something like this:
[(datetime.date(2005, 10, 1), 327.93),
(datetime.date(2005, 1, 1), 133.05),
(datetime.date(2005, 7, 1), 500.95),
(datetime.date(2005, 4, 1), 254.22)]
After that, sorting chronologically is as simple as sorted(date_lst).
The best way to do this, redefining a sort, would be to make a new class or a new function. The default sort algorithms in Python use traditional lexicographical sorting. Calling sort(tuple) will sort them in alphabetical/alphanumeric order, but not necessarily the order you want.
I will note, sorting by default will sort the tuples based on their index [0] value, only going to index [1] if two first indices are the same.
dont name your variable list!!!
sorted(the_list, key=lambda x: list(reversed(map(int,x[0][1:].split("-")))))
Using an object with __lt__ and/or __cmp__ would be good, but if you want to use a key function:
#!/usr/local/cpython-3.3/bin/python
list_ = [('Q4-2005', 327.93), ('Q1-2005', 133.05), ('Q3-2005', 500.95), ('Q2-2005', 254.22), ('Q1-2006', 123.45), ('Q2-2007', 678.90), ]
def key(element):
subresult1 = element[0]
subresult2 = subresult1.split('-')
subresult2.reverse()
subresult2[0] = int(subresult2[0])
return subresult2
list_.sort(key=key)
print(list_)
Which out for the years - they're more significant than the quarters.
I am trying to sort a dictionary of tuples where the second item contains the dates to be sorted.
The dictionary looks something like this:
time_founded: {Soonr: 2005-5-1, SpePharm: 2006-9-1, and so on...}
Right now I am trying to sort the dates like this:
dict = sortedLists[category]
sortedtime = sorted(dict.iteritems(), key=lambda d: map(int, d.split('-')))
But I am getting an error because it is trying to sort the tuples (Soonr: 2005-5-1) instead of just the date.
How can I update the sorting parameters to tell it to only look at the date on not the whole tuple?
Try this:
sortedtime = sorted(dict.iteritems(), key=lambda d: map(int, d[1].split('-')))
The only difference is the [1] which selects out the value portion of the item.
Not sure if you have control over the data structure, but if you do, please change the first element of the data structure to be the date you need to sort by. Python sorts iterables by the first element it finds, or, it can sort by a key you define.
I'd recommend you make it a tuple, with a dictionary in it, to simplify things:
>>> dates = [ ('2006-9-1', {Soonr:'2005-5-1'}),
('2006-8-9', {Soonr:'2005-8-28'})
]
>>> dates.sort() #will sort by the first element of the list items, if iterable...
>>> dates
[('2006-8-9', {Soonr:'2005-8-28'}), ('2006-9-1', {Soonr:'2005-5-1'})]