Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python dictionary is not staying in order

I created a dictionary of the alphabet with a value starting at 0, and is increased by a certain amount depending on the word file. I hard coded the initial dictionary and I wanted it to stay in alphabetical order but it does not at all. I want it to return the dictionary in alphabetical order, basically staying the same as the initial dictionary.

How can i keep it in order?

from wordData import*

def letterFreq(words):
    
    totalLetters = 0
    letterDict = {'a':0,'b':0,'c':0,'d':0,'e':0,'f':0,'g':0,'h':0,'i':0,'j':0,'k':0,'l':0,'m':0,'n':0,'o':0,'p':0,'q':0,
                  'r':0,'s':0,'t':0,'u':0,'v':0,'w':0,'x':0,'y':0,'z':0}

    for word in words:
        totalLetters += totalOccurences(word,words)*len(word)
        for char in range(0,len(word)):
            for letter in letterDict:
                if letter == word[char]:
                    for year in words[word]:
                        letterDict[letter] += year.count
    for letters in letterDict:
        letterDict[letters] = float(letterDict[letters] / totalLetters)
    print(letterDict)
    return letterDict

def main():
   
    filename = input("Enter filename: ")
    words = readWordFile(filename)
    letterFreq(words)


if __name__ == '__main__':
    main()
like image 523
Cos Avatar asked Dec 03 '14 01:12

Cos


People also ask

Does Python dictionary keep order?

Since dictionaries in Python 3.5 don't remember the order of their items, you don't know the order in the resulting ordered dictionary until the object is created. From this point on, the order is maintained. Since Python 3.6, functions retain the order of keyword arguments passed in a call.

Why is dictionary not in order?

First, a Dictionary has no guaranteed order, so you use it only to quickly look up a key and find a corresponding value, or you enumerate through all the key-value pairs without caring what the order is.

Do dictionaries in Python 3.7 have order?

Changed in version 3.7: Dictionary order is guaranteed to be insertion order. This behavior was an implementation detail of CPython from 3.6. Changed in version 3.7: Dictionary order is guaranteed to be insertion order.

Are dictionaries automatically sorted Python?

Note: If you decide that you are not using the optional parameter key and reverse. Python will automatically sort the items in ascending order.


3 Answers

Update for Python 3.7+:

Dictionaries now officially maintain insertion order for Python 3.7 and above.


Update for Python 3.6:

Dictionaries maintain insertion order in Python 3.6, however, this is considered an implementation detail and should not be relied upon.


Original answer - up to and including Python 3.5:

Dictionaries are not ordered and don't keep any order for you.

You could use an ordered dictionary, which maintains insertion order:

from collections import OrderedDict
letterDict = OrderedDict([('a', 0), ('b', 0), ('c', 0)])

Or you could just return a sorted list of your dictionary contents

letterDict = {'a':0,'b':0,'c':0}
sortedList = sorted([(k, v) for k, v in letterDict.iteritems()])

print sortedList # [('a', 0), ('b', 0), ('c', 0)]
like image 86
101 Avatar answered Nov 12 '22 01:11

101


You're only needing the keys in order once, so:

# create letterDict as in your question    
keys = list(letterDict)
keys.sort()
for key in keys:
    # do whatever with letterDict[key]

If you needed them in order more than once, you could use the standard library's collections.OrderedDict. Sometimes that's all you need. It preserves dictionary key order by order of addition.

If you truly need an ordered-by-keys dictionary type, and you don't need it just once (where list_.sort() is better), you could try one of these: http://stromberg.dnsalias.org/~dstromberg/datastructures/

With regard to the above link, if your keys are getting added in an already-sorted order, you're probably best off with a treap or red-black tree (a treap is better on average, but red-black trees have a lower standard deviation). If your keys are (always) getting added in a randomized order, then the simple binary tree is better.

BTW, current fashion seems to favor sorted(list_) over list_.sort(), but sorted(list_) is a relatively recent addition to the language that we got along fine without before it was added, and it's a little slower. Also, list_.sort() doesn't give rise to one-liner-abuse the way sorted(list_) does.

Oh, and vanilla dictionaries are unordered - that's why they're fast for accessing arbitrary elements (they're built on a hash table). Some of the types at datastructures URL I gave above are good at dict_.find_min() and dict_.find_max() and obviate keys.sort(), but they're slower (logn) at accessing arbitrary elements.

like image 37
user1277476 Avatar answered Nov 12 '22 00:11

user1277476


You can sort your dictionary's keys and iterate over your dict.

>>> for key in sorted(letterDict.keys()):
...     print ('{}: {}').format(key, letterDict.get(key))
...
a: 0
b: 0
c: 0
d: 0
e: 0
...

OR

This can be a possible solution in your case. We can have all your dictionary's keys in list whose sequence doesn't change and then we can get values in that order from your dictionary.

>>> import string
>>> keys = list(string.ascii_lowercase)
>>> letterDict = {'a':0,'b':0,'c':0,'d':0,'e':0,'f':0,'g':0,'h':0,'i':0,'j':0,'k':0,'l':0,'m':0,'n':0,'o':0,'p':0,'q':0,
...                   'r':0,'s':0,'t':0,'u':0,'v':0,'w':0,'x':0,'y':0,'z':0}
>>> for key in keys:
...      if key in letterDict:
...         print ('{}: {}').format(key, letterDict.get(key))
...
a: 0
b: 0
c: 0
d: 0
e: 0
f: 0
g: 0
h: 0
i: 0
j: 0
k: 0
l: 0
m: 0
....
like image 20
Tanveer Alam Avatar answered Nov 12 '22 01:11

Tanveer Alam