Ordered Dictionary in Python - python

I have a Dictionary in Python such as this:
dict = {'a':1, 'q':1, 'l':2, 'm':1, 'u':1, 'i':1}
Is there any way that I can keep the order of this dictionary expressed this way. I have read already several forums and most of them suggest using OrderedDict(). But as explained here:
Python OrderedDict not keeping element order
OrderedDict(dict) will not keep the order when the dictionary is written in that form. I can not manually create the dictionary in an specific way (e.g list of tuples) because it is randomly generated by the code elsewhere.
Thank you very much for you help!!

The moment you write dict = {'a':1, 'q':1, 'l':2, 'm':1, 'u':1, 'i':1}, you already have lost the order of the elements. The ways to keep it:
a. Create OrderedDict from your data in the first place.
b. Convert your dict to a list of tuples and sort in a way you want, then create OrderedDict from it.
All in all, from your question it is not clear what you want to preserve. If it is generated "randomly" then who cares, if there is some logic behind it, then use this logic to recreate that order and create OrderedDict using it. If there is something happening behind the scenes which creates this dict from some input data, then, alas, the order in which you see it is not the order in which it has been created.
PS And don't call your dict dict.

If the dictionary you want to order is created outside of your control, you might use the following to get its key:value pairs as a list of tuples:
pairs = my_dict.items()
You can then sort this list any way you like. When you've done that, you can pass the ordered list of pairs to the OrderedDict constructor
from collections import OrderedDict
# sort in some way (for example, reverse the key order)
pairs = reversed(my_dict.items())
ordered = OrderedDict(pairs)

Just use 2 for:
dict = {'a':4, 'q':1, 'l':2, 'm':4, 'p':1}
i = max(dict.values())+1
for el in range (i):
for letter in dict:
if el==dict[letter]:
print(letter,dict[letter])

Related

Is there a way to select particular key value of dictionary present in a list of dictionaries

I am presently using a for loop to print all the required key value pairs of a dictionary. However is there a simpler way to select the required key value pair?
for i in (out['elements']):
out = (i['insights'][0]['details']['socialInfo'])
out_temp.append(out)
The content of out is actually a JSON with list of dictionaries and each dictionary contains a list of dictionaries.
You can use map to generate the new list as well. But I think what you are doing is fine, it is much easier to read than the alternatives.
out_temp = list(map(lambda x: x['insights'][0]['details']['socialInfo'], out['elements']))
I cannot see an unequivocally simpler way to access the data you require. However, you can apply your logic more efficiently via a list comprehension:
out_temp = [i['insights'][0]['details']['socialInfo'] for i in out['elements']]
Whether or not this is also simpler is open to debate.

Python loading sorted json Dict is inconsistent in Windows and Linux

I am using Python 3.6 to process the data I receive in a text file containing a Dict having sorted keys. An example of such file can be:
{"0.1":"A","0.2":"B","0.3":"C","0.4":"D","0.5":"E","0.6":"F","0.7":"G","0.8":"H","0.9":"I","1.0":"J"}
My data load and transform is simple - I load the file, and then transform the dict into a list of tuples. Simplified it looks like this:
import json
import decimal
with open('test.json') as fp:
o = json.loads(fp.read())
l = [(decimal.Decimal(key), val) for key, val in o.items()]
is_sorted = all(l[i][0] <= l[i+1][0] for i in range(len(l)-1))
print(l)
print('Sorted:', is_sorted)
The list is always sorted in Windows and never in Linux. I know that I can sort the list manually, but since the data file is always sorted already and rather big, I'm looking for a different approach. Is there a way to somehow force json package to load the data to my dict sorted in both Windows and Linux?
For the clarification: I have no control over the structure of data I receive. My goal is to find the most efficient method to load the data into the list of tuples for further processing from what I get.
A dictionary is just a mapping between its keys and corresponding values. It doesn't have any order. It doesn't make sense to say you always find them sorted. In addition, any dictionary member access is O(1) so it's probably fast enough for your need. In case you think you still need some order, ordered dictionary may be useful.
Dicts are unordered objects in Python, so the problem you're running into is actually by design.
If you want to get a sorted list of tuples, you can do something like:
sorted_tuples = sorted(my_dict.items(),key=lambda x:x[0])
or
import operator
sorted_tuples = sorted(my_dict.items(),key=operator.itemgetter(0)
The dict method .items() converts the dict to a list of tuples and sorted() sorts that list. The key parameter to sorted explains how to sort the list. Both lambda x: x[0] and operator.itemgetter(0) select the first element of the tuple (the key from the original dict), and sort on that element.

Python reversed mapping / dictionary with unhashable type?

I've created a dictionary like
d = {1: {"a":1, "b":2}, 2: {"a":1, "b":2}}
I'm looping through objects to create dictionaries like the above.
I also want to create a reverse of the above dictionary while I loop, it should look like
d2 = {{"a":1, "b":2}: 1, {"a":1, "b":2}: 2}
I know that the dictionary is an unhashable type, but at the same time I want the ability to reverse look up values without looping through the dictionary.
Is there some way to do this in python?
I also want to create a reverse of the above dictionary while I loop,
it should look like
No, you can't. All keys to a dictionary should be hash-able and a dictionary is not hash-able
Key's cannot have duplicate entries
Is there some way to do this in python?
Unless you wan't the key's to be dictionary, you can convert to some other data structure. May be frozenset of item lists?
If you need duplicate keys, use frozenset of item lists with MultiMap 1.0.3
And google returned me an implementation of frozen dict, you can use it with MultiMap 1.0.3

Complex python dictionary sort by value

I have a dictionary with ints for keys, and strings for values. I need to to sort by the strings, so that when I go dict.values() I get the sorted list.
The strings are values like this: 45_12_something_23
I need to sort numbers as numbers and strings as strings. A given row is guaranteed to be either a string or a number (not a mixture).
Whats a good way to do this in python? Performance isnt an issue.
Convert your dictionary to a list of (key,value) pairs. Sort them however you'd like. (Or is that your question - how to do that?) Then insert the sorted (key,value) pairs into a collections.OrderedDict, which will remember the insertion order and use the same order when iterating.
Note that you can't modify the dict you already have, this will make a new dict with the properties you want.

How to do implement a paging solution with a dict object in Python

Is there a better way to implement a paging solution using dict than this?
I have a dict with image names and URLs.
I need to 16 key value pairs at a time depending on the user's request, i.e. page number.
It's a kind of paging solution.
I can implement this like:
For example :
dict = {'g1':'first', 'g2':'second', ... }
Now I can create a mapping of the keys to numbers using:
ordered={}
for i, j in enumerate(dict):
ordered[i]=j
And then retrieve them:
dicttosent={}
for i in range(paegnumber, pagenumber+16):
dicttosent[ordered[i]] = dict[ordered[i]]
Is this a proper method, or will this give random results?
Store g1, g2, etc in a list called imagelist
Fetch the pages using imagelist[pagenumber: pagenumber+16].
Use your original dict (image numbers to urls) to lookup the url for each of those 16 imagenames.
1) Will this give random results ?
Sort of.
Quoting from the official documentation about dict:
Keys and values are iterated over in an arbitrary order which is non-random, varies across Python implementations, and depends on the dictionary’s history of insertions and deletions.
So for your purposes you can't know a priori on what will be the order of your iteration.
OrderedDict is what you're looking for: an OrderedDict is a dict that remembers the order that keys were first inserted.
2) Is this actually a proper method?
It doesn't seem so.
I don't know if there are library that will handle all that information for you (maybe someone else can tell you that), but it seems like you're trying to emulate the OrderedDict behaviour.
You can directly use an OrderedDict, or if you want to enumerate your info a list can do that.
It depends. If your dict doesn't change during the lifetime of the application and you don't care about ordering of the items in your dict you should be ok.
If not, you should probably use collections.OrderedDict or keep a sorted list of keys, depending on your requirements. Using normal dict doesn't give you any guarantees about iteration order, so after each modification of the input dict you can get different results.
Why not just create a dict that maps to your pages? You could start off with two lists, one containing your image names and the other containing the URLs.
perPage = 16
nameList = ['g1', 'g2', ... ]
urlList = ['first', 'second', ... ]
# This is a generator expression that can create
# the nested dicts. You can also use a simple
# for loop
pageDict = dict(( (i, dict(( (nameList[j], urlList[j])
for j in range(i*perPage, i*perPage+perPage))))
for i in range(len(nameList) / perPage)))
It indexes from 0, so your first page will be pageDict[0].
...Now that I look at it again, that generator expression looks kind of awful. :|

Categories

Resources