Reputation: 129
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()
Upvotes: 5
Views: 7276
Reputation: 8989
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)]
Upvotes: 16
Reputation: 29876
I wouldn't implement it that way. It's pretty hard to read. Something more like this:
# Make sure that division always gives you a float
from __future__ import division
from collections import defaultdict, OrderedDict
from string import ascii_lowercase
...
letterDict = defaultdict(int)
...
# Replace the for char in range(0,len(word)): loop with this
# Shorter, easier to understand, should be equivalent
for year in words[word]:
for char in word:
letterDict[char] += year.count
...
# Filter out any non-letters at this point
# Note that this is the OrderedDict constructor given a generator that creates tuples
# Already in order since ascii_lowercase is
letterRatio = OrderedDict((letter, letterDict[letter] / totalLetters) for letter in ascii_lowercase)
print(letterRatio)
return letterRatio
...
Now that you're returning an OrderedDict
, the order will be preserved. I do caution you, though. If you really need it to be in order at some point, I would just sort it when you need it in the right order. Don't depend on functions that compute new data to return things in a specific sort order. Sort it when you need it sorted, and not before.
Upvotes: 0
Reputation: 2909
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.
Upvotes: 2
Reputation: 5275
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
....
Upvotes: 1