python dictionary sorting oddly (want non-alphabetical) - python

so I am trying to send a packet with some keys that i have put into a dictionary. these need to be printed in a specific order, so I've tried to make a function to reorder them. I assume python is doing something to rearrange in the order I don't want, but i'm not sure why.
I'm currently using this function to try and achieve this.
def array_sort(array, sort): #yeah, it's array cuz i php like that.
ordered = {}
for i in range(0,len(sort)):
if sort[i] in array:
ordered[sort[i]] = array[sort[i]]
keys = array.keys()
return ordered
order = "l5,l4,l3,l2,q,y,k,k3,d1,z,p,c,b,d3,dt,N,n,a,h,v".split(',')
keys = array_sort(infos, order)
for some reason this isn't working, infos is the list of keys in alphabetical order, i'm just not sure why the function is outputting the keys in an odd order. (a first, when 15 should be first :S)
If you know a better way to do this feel free to tell me, I just recently started on python, so I'm not that familiar.
EDIT:
I was able to print the keys in the correct order using this immediately after making the order dictionary. even if it was just output as a string the order would be preserved (for the time being) and you could .split() it again to get the dictionary in the correct order (i think).
for i in range(0, len(order)):
if order[i] in infos:
packet += order[i] + '="' + infos[order[i]] + '" '

Since dictionaries in Python are unordered and all that you need is to output results ordered by the specified rule you can do something like this:
order = "l5,l4,l3,l2,q,y,k,k3,d1,z,p,c,b,d3,dt,N,n,a,h,v".split(',')
for key in order:
print key, infos.get(key)#if infos is your dictionary
Or you can get/pass list instead of dict the following way:
print [(key, infos.get(key)) for key in order]

Python dictionaries are not ordered containers. Take a look at the collections.OrderedDict instead

Python dictionaries order their keys based on its hash, which will make it seem random. I recommend using OrderedDict to get your keys in order.

Related

why use a dictionary if a List combined with Tuples offers way more flexibility?

new to Python, trying to learn how to use dictionaries, but honestly don't see the point, you're limited to 2 pairs whereas if I just make a list with Tuples I get far more flexibility
in the code below I made a list of superheroes, where u can look it up by
Name(Batman), Identity (Bruce Wayne) or Universe (DC)
can't do that on a dictionary (you're limited to pairs of 2) so why would I ever need a dictionary?
Superheroes = [('Batman','Bruce Wayne','DC'),('Spiderman','Peter Parker','Marvel'),('Superman','Clark Kent','DC'),('Ironman','Tony Stark','Marvel'),('Green Arrow','Oliver Queen','DC')]
user_selection = input()
for (name,identity,universe) in Superheroes:
if name==user_selection or identity == user_selection or universe == user_selection:
print('Hero:' + name + '\nSecret Identity:' + identity + '\nUniverse:'+ universe)
else:
continue
Most uses of dictionaries don't require searching for a match in both the keys and values. You design your data structure so that the item you normally need to look up is the dictionary key.
For instance, if you have data with ingredients in recipes, you would almost always be looking it up by the dish that you're cooking. So you make that the key and you can get all the ingredients with a single lookup instead of searching the entire list.
If you occasionally need to find something in the value, you can still iterate through the dictionary using dict.entries(). If you need to look up by different components frequently you can make multiple dictionaries that all refer to the same values using different keys.

Python Dictionary with Variable Array keys

self.PARSE_TABLE={"$_ERROR":self.WEEK_ERRORS,"$_INFORM":self.WEEK_INFORM,"$_REDIR":self.WEEK_REDIRECTS,"$_SERVER_ERROR":self.WEEK_SERVER_ERROR,"$_BYTES":self.WEEK_BYTES,"$_HITS":self.WEEK_HITS}
for j in self.PARSE_TABLE:
print j
break
When I run this on my python the first element I get is S_REDIR can someone explain why?
Dictionaries don't maintain order. The order you get from iterating over them may not be the order in which you inserted the elements. This is the price you pay for near-instant lookup of values by key. In short, the behavior you are seeing is correct and expected, and may even vary from run to run of the Python interpreter.
It normal behaviour. Inside dictionary and set using hash codes. If you want orderd keys use self.PARSE_TABLE.keys.sort(). Also you can use OrderedDict from collection library.
Dictionary by default stores all the keys in its own convenient order rather to the order we gave.
If the order of the keys should be maintained, you can use OrderedDict which came to implementation from the python version 3.0
P.S. I don't think sorting keys would do any help in preserving the order given.

Look up python dict value by expression

I have a dict that has unix epoch timestamps for keys, like so:
lookup_dict = {
1357899: {} #some dict of data
1357910: {} #some other dict of data
}
Except, you know, millions and millions and millions of entries. I'd like to subset this dict, over and over again. Ideally, I'd love to be able to write something like I can in R, like:
lookup_value = 1357900
dict_subset = lookup_dict[key >= lookup_value]
# dict_subset now contains {1357910: {}}
But I confess, I can't find any actual proof that this is something Python can do without having, one way or the other, to iterate over every row. If I understand Python correctly (and I might not), key lookup of the form key in dict uses binary search, and is thus very fast; any way to do a binary search, on dict keys?
To do this without iterating, you're going to need the keys in sorted order. Then you just need to do a binary search for the first one >= lookup_value, instead of checking each one for >= lookup_value.
If you're willing to use a third-party library, there are plenty out there. The first two that spring to mind are bintrees (which uses a red-black tree, like C++, Java, etc.) and blist (which uses a B+Tree). For example, with bintrees, it's as simple as this:
dict_subset = lookup_dict[lookup_value:]
And this will be as efficient as you'd hope—basically, it adds a single O(log N) search on top of whatever the cost of using that subset. (Of course usually what you want to do with that subset is iterate the whole thing, which ends up being O(N) anyway… but maybe you're doing something different, or maybe the subset is only 10 keys out of 1000000.)
Of course there is a tradeoff. Random access to a tree-based mapping is O(log N) instead of "usually O(1)". Also, your keys obviously need to be fully ordered, instead of hashable (and that's a lot harder to detect automatically and raise nice error messages on).
If you want to build this yourself, you can. You don't even necessarily need a tree; just a sorted list of keys alongside a dict. You can maintain the list with the bisect module in the stdlib, as JonClements suggested. You may want to wrap up bisect to make a sorted list object—or, better, get one of the recipes on ActiveState or PyPI to do it for you. You can then wrap the sorted list and the dict together into a single object, so you don't accidentally update one without updating the other. And then you can extend the interface to be as nice as bintrees, if you want.
Using the following code will work out
some_time_to_filter_for = # blah unix time
# Create a new sub-dictionary
sub_dict = {key: val for key, val in lookup_dict.items()
if key >= some_time_to_filter_for}
Basically we just iterate through all the keys in your dictionary and given a time to filter out for we take all the keys that are greater than or equal to that value and place them into our new dictionary

Dive Into Python Output Error

I'm running this code from Dive Into Python:
def buildConnectionString(params):
"""Build a connection string from a dictionary of parameters.
Returns string."""
return ";".join(["%s=%s" % (k, v) for k, v in params.items()])
if __name__ == "__main__":
myParams = {"server":"mpilgrim", \
"database":"master", \
"uid":"sa", \
"pwd":"secret" \
}
print buildConnectionString(myParams)
The book says its output should be:
server=mpilgrim;uid=sa;database=master;pwd=secret
But when I run it it comes out in reverse:
pwd=secret;database=master;uid=sa;server=mpilgrim
Any ideas why?
The fact that it is in exactly reverse order is really just a coincidence. Run the code with a different version/implementation of python and you'll likely get a different ordering. The reason for this is because in python dictionaries are not ordered so the order of the ouput of your function is not well defined. (The order that you put things into the dictionary is not the order that they are yielded as you iterate over the dictionary).
If you want a specific order, you can sort parames.items() using the builtin sorted function (optionally using the key keyword to tell sorted how to sort the items). Another option is to use an OrderedDict from the collections module which appeared in python2.7 (as pointed out by sr2222).
Because you are printing a dictionary, and dictionaries are unordered. The order a dictionary is iterated through is dependent on a number of factors including interpreter type, interpreter version, and OS. If you want it to come out the same order you put it in, you have to use collections.OrderedDict instead. Alternatively, as mgilson said in his answer, you could sort the dictionary contents before printing it, but given that the order you want is not alphabetical, it's probably more trouble than it is worth.

python : how to disable auto sort when creating dictionary

i need help for this case :
m={}
m[1]=1
m[333]=333
m[2]=2
# Result:
{1: 1, 2: 2, 333: 333}
so even when i didn't enter '333' the last, i got this '333' listed in the end of the dictionary when print it out. why is this 'dictionary' doing auto sort? and how disable it? i can creata a function to re-sort to fix the order. but that's not what i want, i just simply want to print and get output order just like the order when i input the data. Is there any good explanation and is there any solution ?
It is not sorting. dict is not ordered at all, so you cannot influence the key order in any way. There is collections.OrderedDict in 2.7 and 3.1+, there is also standalone module for 2.4-2.6.
Items stored in a dictionary do not have any inherent order. The order they are printed out is entirely down to the hash values for each of the keys and the other items in the dictionary.
Long time after this questions was posted, but just for those who land on this page, since 3.6? dictionaries preserve the order that items are added in.

Categories