I have a following dictionary :
{2009: [12, 11, 10, 9], 2010: [1]}
I'm trying to reverse-sort it, so that 2010 comes first. Here's the code :
def dictSort(dict):
items = dict.items()
items.sort(reverse=True)
dict = {}
for item in items:
dict[item[0]] = item[1]
return dict
But in return I get the same dictionary. Until the for loop everything looks fine. Why is that ?
Dictionary keys are not ordered. Think of a dict as a set of key/value pairs.
This is coming in Python 3.1:
http://docs.python.org/dev/library/collections.html#collections.OrderedDict
A dictionary is unordered, whatever you put into it isn't stored in the order you add to it.
If you want to do something to it in sorted order, you can do:
items = dict.items.sort(reverse=True)
for item in items:
doSomething(item,mydict[item])
or
for key,value in iter(sorted(mydict.iteritems(),reverse=True))
doSomething(key,value)
Dictionaries don't have an order. If you are trying to output the dictionary in a certain order, try grabbing all the keys, sorting them, and using that list to know which order to output things.
Here one way to generate items of dict in reversed order of key (BTW please do not use dict for variable name!):
def dict_sort(thisdict, reverse=True):
return ((key, thisdict[key]) for key in sorted(thisdict, reverse=reverse))
mydict = {2009: [12, 11, 10, 9], 2010: [1]}
for i in dict_sort(mydict):
print "%i: %s" % i
Related
Say I have two dictionaries:
dict_one = {abc: 5, bat: 1, car: 6, xray: 3}
dict_two = {abc: 2, jfk: 4, zit: 7}
I want to compare the keys of both and create a new dictionary which contains only the keys of dict_one which don't occur in dict_two.
The new dictionary would look like this:
unique_dict = {bat: 1, car: 6, xray: 3}
This is what I am trying at the moment (the first part found here: Python read two dictionaries compare values and create third dictionary)
However I know the problem is that I can't update(key, value) as it takes only one argument, but I just don't know how to do this correctly.
d1_values = set(dict_one.keys())
d2_values = set(dict_two.keys())
words_in_both = d1_values & d2_values
not_in_both = d1_values ^ d2_values
unique_dict = {}
for key, value in dict_one.items():
for word in words_in_both:
if key != word:
unique_dict.update(key, value) # this is not correct
You could use the following dictionary comprehension to keep the key/value pairs in dict_one if they are not in dict_two:
{k:v for k,v in dict_one.items() if k not in dict_two}
# {'bat': 1, 'car': 6, 'xray': 3}
Sets and dict views already support subtraction to keep only the values in the left hand side not found in the right. So your code could simplify to:
{k: dict_one[k] for k in dict_one.keys() - dict_two.keys()}
yatu's answer is probably better in this specific case (no set temporary required), but I figured I'd point out set/view subtraction as well as showing no conversion to set itself is necessary (views can be used as set-like objects already).
def filter_dicts(d1, d2):
"""Return d1 items that are not in d2"""
return {title: value for title, value in d1.items() if title not in d2}
I want to sort a list of dictionaries based on the presence of keys. Let's say I have a list of keys [key2,key3,key1], I need to order the list in such a way the dictionary with key2 should come first, key3 should come second and with key1 last.
I saw this answer (Sort python list of dictionaries by key if key exists) but it refers to only one key
The sorting is not based on value of the 'key'. It depends on the presence of the key and that too with a predefined list of keys.
Just use sorted using a list like [key1 in dict, key2 in dict, ...] as the key to sort by. Remember to reverse the result, since True (i.e. key is in dict) is sorted after False.
>>> dicts = [{1:2, 3:4}, {3:4}, {5:6, 7:8}]
>>> keys = [5, 3, 1]
>>> sorted(dicts, key=lambda d: [k in d for k in keys], reverse=True)
[{5: 6, 7: 8}, {1: 2, 3: 4}, {3: 4}]
This is using all the keys to break ties, i.e. in above example, there are two dicts that have the key 3, but one also has the key 1, so this one is sorted second.
I'd do this with:
sorted_list = sorted(dict_list, key = lambda d: next((i for (i, k) in enumerate(key_list) if k in d), len(key_list) + 1))
That uses a generator expression to find the index in the key list of the first key that's in each dictionary, then use that value as the sort key, with dicts that contain none of the keys getting len(key_list) + 1 as their sort key so they get sorted to the end.
How about something like this
def sort_key(dict_item, sort_list):
key_idx = [sort_list.index(key) for key in dict_item.iterkeys() if key in sort_list]
if not key_idx:
return len(sort_list)
return min(key_idx)
dict_list.sort(key=lambda x: sort_key(x, sort_list))
If the a given dictionary in the list contains more than one of the keys in the sorting list, it will use the one with the lowest index. If none of the keys are present in the sorting list, the dictionary is sent to the end of the list.
Dictionaries that contain the same "best" key (i.e. lowest index) are considered equal in terms of order. If this is a problem, it wouldn't be too hard to have the sort_key function consider all the keys rather than just the best.
To do that, simply return the whole key_idx instead of min(key_idx) and instead of len(sort_list) return [len(sort_list)]
dict:
d1 = {'b,a':12,'b,c,a':13}
Code:
x = collections.OrderedDict(sorted(d1.items()))
print(x)
Not getting the expected output.
Expected Output:
d1 = {'a,b': 12, 'a,b,c':13}
It looks like you don't actually want to sort the keys, you want to re-arrange the non-comma substrings of your keys such that these substrings are ordered.
>>> d1 = {'b,a':12,'b,c,a':13}
>>> {','.join(sorted(key.split(','))):val for key, val in d1.items()}
{'a,b': 12, 'a,b,c': 13}
d1.items(): returns a list of (key, value) tuples
sorted(d1.items()): simply sorts the above list
If you want to sort the items in your keys, then you need to run sort on your keys.
I have a list of dictionaries, of the form:
neighbour_list = [{1:4}, {3:5}, {4:9}, {5:2}]
I need to sort the list in order of the dictionary with the largest value. So, for the above code the sorted list would look like:
sorted_list = [{4:9}, {3:5}, {1:4}, {5:2}]
Each dictionary within the list only has one mapping.
Is there an efficient way to do this? Currently I am looping through the list to get the biggest value, then remembering where it was found to return the largest value, but I'm not sure how to extend this to be able to sort the entire list.
Would it just be easier to implement my own dict class?
EDIT: here is my code for returning the dictionary which should come 'first' in an ideally sorted list.
temp = 0
element = 0
for d in list_of_similarities:
for k in d:
if (d[k] > temp):
temp = d[k]
element = k
dictionary = d
first = dictionary[element]
You can use an anonymous function as your sorting key to pull out the dict value (not sure if i've done this the most efficient way though:
sorted(neighbour_list, key = lambda x: tuple(x.values()), reverse=True)
[{4: 9}, {3: 5}, {1: 4}, {5: 2}]
Note we need to coerce x.values() to a tuple, since in Python 3, x.values() is of type "dict_values" which is unorderable. I guess the idea is that a dict is more like a set than a list (hence the curly braces), and there's no (well-) ordering on sets; you can't use the usual lexicographic ordering since there's no notion of "first element", "second element", etc.
You could list.sort using the dict values as the key.
neighbour_list.sort(key=lambda x: x.values(), reverse=1)
Considering you only have one value, for python2 you can just call next on itervalues to get the first and only value:
neighbour_list.sort(key=lambda x: next(x.itervalues()), reverse=1)
print(neighbour_list)
For python3, you cannot call next on dict.values, it would have to be:
neighbour_list.sort(key=lambda x: next(iter(x.values())), reverse=1)
And have to call list on dict.values:
neighbour_list.sort(key=lambda x: list(x.values()), reverse=1)
How do you remove all elements from the dictionary whose key is a element of a list?
for key in list_:
if key in dict_:
del dict_[key]
[Note: This is not direct answer but given earlier speculation that the question looks like homework. I wanted to provide help that will help solving the problem while learning from it]
Decompose your problem which is:
How to get a element from a list
How to delete a key:value in dictionary
Further help:
How do get all element of a list on python?
For loop works on all sequences and list is a sequence.
for key in sequence: print key
How do you delete a element in dictionary?
use the del(key) method.
http://docs.python.org/release/2.5.2/lib/typesmapping.html
You should be able to combine the two tasks.
map(dictionary.__delitem__, lst)
d = {'one':1, 'two':2, 'three':3, 'four':4}
l = ['zero', 'two', 'four', 'five']
for k in frozenset(l) & frozenset(d):
del d[k]
newdict = dict(
(key, value)
for key, value in olddict.iteritems()
if key not in set(list_of_keys)
)
Later (like in late 2012):
keys = set(list_of_keys)
newdict = dict(
(key, value)
for key, value in olddict.iteritems()
if key not in keys
)
Or if you use a 2.7+ python dictionary comprehension:
keys = set(list_of_keys)
newdict = {
key: value
for key, value in olddict.iteritems()
if key not in keys
}
Or maybe even a python 2.7 dictionary comprehension plus a set intersection on the keys:
required_keys = set(olddict.keys()) - set(list_of_keys)
return {key: olddict[key] for key in required_keys}
Oh yeah, the problem might well have been that I had the condition reversed for calculating the keys required.
for i in lst:
if i in d.keys():
del(d[i])
I know nothing about Python, but I guess you can traverse a list and remove entries by key from the dictionary?