I have a dictionary. The keys are dates (datetime). I need to sort the dictionary so that the values in the dictionary are sorted by date - so that by iterating through the dictionary, I am processing items in the desired chronological (i.e. date/time) order.
How may I sort such a dictionary by date?
Example:
mydict = { '2000-01-01': {fld_1: 1, fld_2: 42}, '2000-01-02': {fld_1:23, fld_2: 22.17} }
Note: I am using strings here instead of datetime, to keep the example simple
If you're using Python 2.7+ or 3.1+ you could create an OrderedDict from collections from a sort of your dictionary and then iterate through that.
from collections import OrderedDict
ordered = OrderedDict(sorted(mydict.items(), key=lambda t: t[0]))
However, depending on what you want to do it's probably easier to iterate over a sorted list of keys from your dict.
Dictionaries are unsortable. Iterate over sorted(mydict.keys()) instead.
Dictionaries never store anything in some order. But you can get a list of keys using d.keys() which could be sorted. Iterate over a generator like below.
def sortdict(d):
for key in sorted(d): yield d[key]
Using this you will be able to iterate over values in chronological order.
for value in sortdict(mydict):
# your code
pass
since your date strings seem to be in a proper format you could just do:
>>> sorted(mydict.items()) # iteritems in py2k
[('2000-01-01', {'fld_2': 42, 'fld_1': 1}), ('2000-01-02', {'fld_2': 22.17, 'fld_1': 23})]
I'm sure that python knows how to compare dates. So:
def sortedDictValues(adict):
items = adict.items()
items.sort()
return [value for key, value in items]
Python 2.7 (released on July 3rd, 2010) supports an ordered dictionary type:
http://www.python.org/download/releases/2.7/
Related
I got a dict of names as keys and formated dates as values, I managed to have the list of these dates sorted, but I dont know how to now sort my dict with this "custom order", since the dates are weirdly formated, sort() won't work.
Here is an example :
dict = {'Charles':'01/02-21:00','Martin':'01/03-22:00','David':'01/02-19:00'}
The dates are formated as day/month-hour:minute.
The sorted list of dates would be ['01/02-19:00','01/02-21:00','01/03-22:00']
And the wanted dict output {'David':'01/02-19:00','Charles':'01/02-21:00','Martin':'01/03-22:00'}
Use:
[Python.Docs]: Built-in Functions - sorted(iterable, /, *, key=None, reverse=False) to sort the dictionary items
In order to properly compare the dates, each date string (value in the dictionary) needs to be converted to a time.struct_time object. That is done via [Python.Docs]: time.strptime(string[, format])
In the end, the sorted items are re-assembled into a dict
>>> import time
>>>
>>>
>>> d = {"Charles": "01/02-21:00", "Martin": "01/03-22:00", "David": "01/02-19:00"}
>>>
>>> dict(sorted(d.items(), key=lambda arg: time.strptime(arg[1], "%d/%m-%H:%M")))
{'David': '01/02-19:00', 'Charles': '01/02-21:00', 'Martin': '01/03-22:00'}
As a generic piece of advice, try choosing for your identifiers names that aren't already used, as you will shadow previous definitions (in your case: [Python.Docs]: Built-in Functions - class dict(**kwarg)).
I'm trying to match key value from different dictionaries in a list and make them as individual list.Below is the example format
originallist=[
{"A":"Autonomous","C":"Combined","D":"Done"},
{"B":"Bars","A":"Aircraft"},
{"C":"Calculative"}
]
#Note: The dictionaries present in the original list may vary in number
#I was trying to acheive the below format
A=["Autonomous","Aircraft"]
B=["Bars"]
C=["Calculative","Combined"]
D=["Done"]
Thanks in advance for your help
The best option would be to use a defaultdict.
from collections import defaultdict
out = defaultdict(list)
#data is the list in question
for rec in data:
for key,value in rec.items():
out[key].append(value)
A defaultdict returns a default value in case the key does not exist. dict.items is a method that returns and iterator of the key value pairs.
You can do it faster using pandas, but it would be overkill unless you have a huge dataset.
How to sort a list of 1 billion elements in python
Please elaborate
Assuming we have unlimited space.
Thanks for the answers, but, this question is asked in the perspective of optimizing algorithm to sort, not to work on python. This question is asked in an interview, in the context of, having large number of elements, may be integers or strings, this probably wont be used in real world as we have techniques like pagination.
Dictionaries are unordered. They are hash tables and you are not guaranteed the order of keys in a hash table.
If you require the keys to be ordered, try the ordered dict class in collections.
If you need to sort the keys you could place them in a list, and sort the list.
my_dict = {key: value for key, value in zip(keys, values)} # Example dict
keys = [i for i in my_dict]
keys.sort()
A dictionary on its own does not store a key order. For this, you will have to use the OrderedDict which stores the order of insertion.
If you just need to iterate through the sorted keys, you can use sorted:
for key in sorted(my_dict):
# output is already sorted by dictionary key
print key, my_dict[key]
if you need to specify a special key or method, you could pass this as information to sorted. The following example sorts by value:
for key, value in sorted(my_dict.items(), key=lambda x: x[1]):
# output is sorted by value
print key, value
Sort orders can be reversed by using reversed:
for key in reversed(sorted(my_dict)):
# output is already sorted descending by dictionary key
print key, my_dict[key]
Finally, this code snippet would fill an OrderedDict with sorted key/value pairs:
from collections import OrderedDict
my_ordered_dict = OrderedDict(sorted(my_dict.items(), key=lambda t: t[0]))
Since you updated your question from dictionary to list
Sorting lists is even easier, just use sorted (again, provide a small method, if you have a different sorting key):
sorted_list = sorted(unsorted_list)
I am reading items from a txt file into a list and then converting it into a dictionary as follows-
def getfeatures_into_list(inputfilename):
fid=open(inputfilename,"r")
dict_Lab_Features=defaultdict(int)
list1=[]
for line in fid:
list1.append(line.rstrip().lower())
list1=list(set(list1)) #Removing duplicates
c=0
for items in sorted(list1):
dict_Lab_Features[items]=c
c+=1
dict_Lab_Features=sorted(dict_Lab_Features.items(), key=operator.itemgetter(1))
print(dict_Lab_Features['Hello'])
I am getting error in the print statement
list indices must be integer,not str
Edit I want to sort the dict by value in ascending order.
In this line:
dict_Lab_Features=sorted(dict_Lab_Features.items(), key=operator.itemgetter(1))
you have reassigned dict_Lab_Features so that it is a list. This is because the output of sorted() is always a list. Naturally, a list cannot take a string as an index.
You should learn to think of dictionaries as inherently unsorted. There is such a thing as an OrderedDict for when you really need to keep track of insertion order, but for most purposes, a regular dict is fine. You just have to get into the habit of traversing the dictionary in the desired order, not worrying about whether the dictionary is stored in any kind of order.
The usual way to traverse a dictionary in sorted order is to just loop over the sorted keys, such as:
for key in sorted(dict_Lab_Features):
print dict_Lab_Features[key]
or
for key, value in sorted(dict_Lab_Features.items()):
print value
Or, if you want to loop over the sorted values,
for value in sorted(dict_Lab_Features.values()):
print value
You cannot sort a dict. Dicts are unordered mappings of elements.
Let's analyize the following line:
dict_Lab_Features=sorted(dict_Lab_Features.items(), key=operator.itemgetter(1))
From the documentation of sorted:
Return a new sorted list from the items in iterable.
So after that, dict_Lab_Features is a sorted list of key-value tuples. After that you try to index it with 'Hello'
print(dict_Lab_Features['Hello'])
Here you try to index that list with 'Hello', that's why you get the error list indices must be integer,not str
dict_Lab_Features stops being a dict when you call dict.items(). A dict.items() object cannot be addressed using string keys (it's really just a list of tuples [(key, value), ... ]).
Furthermore, "sorting" a dictionary you then intend to use by name doesn't make much sense either. Looks like you either need a collections.OrderedDict or you should skip ordering altogether
I have a dictionary such as below.
d = {
'0:0:7': '19734',
'0:0:0': '4278',
'0:0:21': '19959',
'0:0:14': '9445',
'0:0:28': '14205',
'0:0:35': '3254'
}
Now I want to sort it by keys with time priority.
Dictionaries are not sorted, if you want to print it out or iterate through it in sorted order, you should convert it to a list first:
e.g.:
sorted_dict = sorted(d.items(), key=parseTime)
#or
for t in sorted(d, key=parseTime):
pass
def parseTime(s):
return tuple(int(x) for x in s.split(':'))
Note that this will mean you can not use the d['0:0:7'] syntax for sorted_dict though.
Passing a 'key' argument to sorted tells python how to compare the items in your list, standard string comparison will not work to sort by time.
Dictionaries in python have no guarantees on order. There is collections.OrderedDict, which retains insertion order, but if you want to work through the keys of a standard dictionary in order you can just do:
for k in sorted(d):
In your case, the problem is that your time strings won't sort correctly. You need to include the additional zeroes needed to make them do so, e.g. "00:00:07", or interpret them as actual time objects, which will sort correctly. This function may be useful:
def padded(s, c=":"):
return c.join("{0:02d}".format(int(i)) for i in s.split(c))
You can use this as a key for sorted if you really want to retain the current format in your output:
for k in sorted(d, key=padded):
Have a look at the collections.OrderedDict module