sorting dates in key of tuples in dictionary - python

I have a dictionary with entries that are of the format
a = dict({(2,2013):[], (2,2011):[], (7,2013):[] , (4,2013):[]})
i want my output to be like this:
{(2,2011):[], (2,2013):[], (4,2013):[] , (7,2013):[]}
By the way its supposed to be (month,year), how can i achieve that?

import operator
myDict = {1: 1, 2: 2, 4:4, 2:1}
sorted_myDict = sorted(myDict.iteritems(), key=operator.itemgetter(1))
sorted_myDict will be a list of tuples sorted by the second element in each tuple.
#Decency answer is also very good option.

If you need to retain order for some reason, you can use an OrderedDict object.
Ordered dictionaries are just like regular dictionaries but they remember the order that items were inserted. When iterating over an ordered dictionary, the items are returned in the order their keys were first added.
Docs: http://docs.python.org/2/library/collections.html#collections.OrderedDict
class collections.OrderedDict([items])

after a lot of trying i changed my approach and instead of tuples, i used datetime objects and then applied the:
months_sorted = sorted(months.iteritems(), key=operator.itemgetter(0))

Related

Adding two asynchronous lists, into a dictionary

I've always found Dictionaries to be an odd thing in python. I know it is just me i'm sure but I cant work out how to take two lists and add them to the dict. If both lists were mapable it wouldn't be a problem something like dictionary = dict(zip(list1, list2)) would suffice. However, during each run the list1 will always have one item and the list2 could have multiple items or single item that I'd like as values.
How could I approach adding the key and potentially multiple values to it?
After some deliberation, Kasramvd's second option seems to work well for this scenario:
dictionary.setdefault(list1[0], []).append(list2)
Based on your comment all you need is assigning the second list as a value to only item of first list.
d = {}
d[list1[0]] = list2
And if you want to preserve the values for duplicate keys you can use dict.setdefault() in order to create value of list of list for duplicate keys.
d = {}
d.setdefault(list1[0], []).append(list2)

How can I iterate over a dict which is indexed by a dict?

If I have an iteration like:
for index in my_dict:
print index.keys()
Is index possible to be a dictionary in this case? If possible, could you please give me an example of what my_dict will look like?
index cannot be a dict as dictionary keys must be hashable types. Since dictionaries are themselves not hashable, they can not serve as keys to another dictionary.
for index in my_dict
iterates over the dictionary keys and will yield the same result as
for index in my_dict.keys()
You can however have a dictionary nested as a value of another dictionary:
{'parent': {'nested': 'some value'}}
# ^ nested dictionary ^
Dictionaries are an unhashable type in Python so another dictionary cannot be used for as a key (or index) to a parent dictionary but it can be used as a value.
That dictionary would look something like this:
my_dict = {'example': {'key': 0}}
And if you wanted to loop over it and select the dictionaries rather than the keys the code would look something like this:
for key in my_dict:
print(my_dict[key].keys())
Which if you've been following along with the example should just output ['key'].
It wasn't part of your question but I'd recommend using a tuple for the kind of data storage and access you want, and if you'd like I can show you how to do that as well.

Filtering items within Python dictionary values containing strings of tuples

I need to create a new dictionary from the following:
{'FOO': "('BAR','BAA'),('CAR','CAA')", 'FOOO': "('BAAR','BAAA'),('CAAR','CAAA')"}
I want to retrieve items within the strings of tuples in the dictionary values, and create a new dictionary using the original keys and the retrieved items as corresponding values. The retrieved items must be by placement (first item of every tuple). The completed dictionary should look like the following:
{'FOO': ('BAR','CAR'), 'FOOO': ('BAAR','CAAR')
This should be relatively easy, but I've been pulling my hair out trying to make this work.
You can use ast.literal_eval to parse those strings. Then it's just a matter of pulling out the right elements.
d = {'FOO': "('BAR','BAA'),('CAR','CAA')", 'FOOO': "('BAAR','BAAA'),('CAAR','CAAA')"}
d2 = {k: zip(*ast.literal_eval(v))[0] for k,v in d.iteritems()}
# d2 is now {'FOO': ('BAR', 'CAR'), 'FOOO': ('BAAR', 'CAAR')}
First, ast.literal_eval will turn each "('BAR','BAA'),('CAR','CAA')" into (('BAR', 'BAA'), ('CAR', 'CAA')).
Then you can just do [0] to get the first one. Is that all you were missing?
It's worth noting that, as a general rule, if you're using literal_eval, you're usually doing something wrong. For example, maybe instead of storing a string literal version of a tuple, you can store a JSON array, or a pickled or marshalled tuple.
It might be not the best way to do it, but you can solve it with regular expressions.
import re
di={'FOO': "('BAR','BAA'),('CAR','CAA')",
'FOOO': "('BAAR','BAAA'),('CAAR','CAAA')"}
ndi = {}
for k in di:
ndi[k] = re.findall('\(\'(\w+)\'\,', di[k])

update method for dictionaries-Python

I have written a code which tries to sort a dictionary using the values rather than keys
""" This module sorts a dictionary based on the values of the keys"""
adict={1:1,2:2,5:1,10:2,44:3,67:2} #adict is an input dictionary
items=adict.items()## converts the dictionary into a list of tuples
##print items
list_value_key=[ [d[1],d[0]] for d in items] """Interchanges the position of the
key and the values"""
list_value_key.sort()
print list_value_key
key_list=[ list_value_key[i][1] for i in range(0,len(list_value_key))]
print key_list ## list of keys sorted on the basis of values
sorted_adict={}
*for key in key_list:
sorted_adict.update({key:adict[key]})
print key,adict[key]
print sorted_adict*
So when I print key_list i get the expected answer, but for the last part of the code where i try to update the dictionary, the order is not what it should be. Below are the results obtained. I am not sure why the "update" method is not working. Any help or pointers is appreciated
result:
sorted_adict={1: 1, 2: 2, 67: 2, 5: 1, 10: 2, 44: 3}
Python dictionaries, no matter how you insert into them, are unordered. This is the nature of hash tables, in general.
Instead, perhaps you should keep a list of keys in the order their values or sorted, something like: [ 5, 1, 44, ...]
This way, you can access your dictionary in sorted order at a later time.
Don't sort like that.
import operator
adict={1:1,2:2,5:1,10:2,44:3,67:2}
sorted_adict = sorted(adict.iteritems(), key=operator.itemgetter(1))
If you need a dictionary that retains its order, there's a class called OrderedDict in the collections module. You can use the recipes on that page to sort a dictionary and create a new OrderedDict that retains the sort order. The OrderedDict class is available in Python 2.7 or 3.1.
To sort your dictionnary, you could also also use :
adict={1:1,2:2,5:1,10:2,44:3,67:2}
k = adict.keys()
k.sort(cmp=lambda k1,k2: cmp(adict[k1],adict[k2]))
And by the way, it's useless to reuse a dictionnary after that because there are no order in dict (they are just mapping types - you can have keys of different types that are not "comparable").
One problem is that ordinary dictionaries can't be sorted because of the way they're implemented internally. Python 2.7 and 3.1 had a new class namedOrderedDictadded to theircollectionsmodule as #kindall mentioned in his answer. While they can't be sorted exactly either, they do retain or remember the order in which keys and associated values were added to them, regardless of how it was done (including via theupdate() method). This means that you can achieve what you want by adding everything from the input dictionary to anOrderedDictoutput dictionary in the desired order.
To do that, the code you had was on the right track in the sense of creating what you called thelist_value_keylist and sorting it. There's a slightly simpler and faster way to create the initial unsorted version of that list than what you were doing by using the built-inzip()function. Below is code illustrating how to do that:
from collections import OrderedDict
adict = {1:1, 2:2, 5:1, 10:2, 44:3, 67:2} # input dictionary
# zip together and sort pairs by first item (value)
value_keys_list = sorted(zip(adict.values(), adict.keys()))
sorted_adict = OrderedDict() # value sorted output dictionary
for pair in value_keys_list:
sorted_adict[pair[1]] = pair[0]
print sorted_adict
# OrderedDict([(1, 1), (5, 1), (2, 2), (10, 2), (67, 2), (44, 3)])
The above can be rewritten as a fairly elegant one-liner:
sorted_adict = OrderedDict((pair[1], pair[0])
for pair in sorted(zip(adict.values(), adict.keys())))

python: arbitrary order by

In Oracle SQL there is a feature to order as follow:
order by decode("carrot" = 2
,"banana" = 1
,"apple" = 3)
What is the best way to implement this in python?
I want to be able to order a dict by its keys. And that order isn't necessarily alphabetically or anything - I determine the order.
Use the key named keyword argument of sorted().
#set up the order you want the keys to appear here
order = ["banana", "carrot", "apple"]
# this uses the order list to sort the actual keys.
sorted(keys, key=order.index)
For higher performance than list.index, you could use dict.get instead.
#this builds a dictionary to lookup the desired ordering
order = dict((key, idx) for idx, key in enumerate(["banana", "carrot", "apple"]))
# this uses the order dict to sort the actual keys.
sorted(keys, key=order.get)
You can't order a dict per se, but you can convert it to a list of (key, value) tuples, and you can sort that.
You use the .items() method to do that. For example,
>>> {'a': 1, 'b': 2}
{'a': 1, 'b': 2}
>>> {'a': 1, 'b': 2}.items()
[('a', 1), ('b', 2)]
Most efficient way to sort that is to use a key function. using cmp is less efficient because it has to be called for every pair of items, where using key it only needs to be called once for every item. Just specify a callable that will transform the item according to how it should be sorted:
sorted(somedict.items(), key=lambda x: {'carrot': 2, 'banana': 1, 'apple':3}[x[0]])
The above defines a dict that specifies the custom order of the keys that you want, and the lambda returns that value for each key in the old dict.
Python's dict is a hashmap, so it has no order. But you can sort the keys separately, extracting them from the dictionary with keys() method.
sorted() takes comparison and key functions as arguments.
You can do exact copy of your decode with
sortedKeys = sorted(dictionary, {"carrot": 2
,"banana": 1
,"apple": 3}.get);
You can't sort a dictionary; a dictionary is a mapping and a mapping has no ordering.
You could extract the keys and sort those, however:
keys = myDict.keys()
sorted_keys = sorted(keys, myCompare)
There will be OrderedDict in new Python versions: http://www.python.org/dev/peps/pep-0372/.
Meanwhile, you can try one of the alternative implementations: http://code.activestate.com/recipes/496761/, Ordered Dictionary.
A dict is not ordered. You will need to keep a list of keys.
You can pass your own comparison function to list.sort() or sorted().
If you need to sort on multiple keys, just concatenate them in a tuple, and sort on the tuple.

Categories