字典不是停留在python的顺序

时间:2014-12-03 01:42:09

标签: python python-2.7 python-3.x

我创建了一个字母表字典,其值从0开始,并根据单词文件增加一定量。我对初始字典进行了硬编码,我希望它按字母顺序排列,但它根本不存在。我希望它按字母顺序返回dictionart,基本上和初始字典保持一致。我怎样才能保持秩序?

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()

4 个答案:

答案 0 :(得分:8)

字典不是订购的,不会为您保留任何订单。

您可以使用有序词典:

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

或者你可以只返回你的词典内容的排序列表

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)]

答案 1 :(得分:2)

你只需按顺序一次,所以:

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

如果您不止一次需要它们,您可以使用标准库的collections.OrderedDict。有时这就是你所需要的。它按照添加顺序保留字典键顺序。

如果你真的需要一个按键排序的字典类型,并且你不需要它一次(其中list_.sort()更好),你可以尝试以下方法之一: http://stromberg.dnsalias.org/~dstromberg/datastructures/

关于上述链接,如果您的密钥是按照已排序的顺序添加的,那么您可能最好使用treap或红黑树(treap平均更好,但是红色 - 黑树的标准偏差较小)。如果你的密钥(总是)以随机顺序添加,那么简单的二叉树就更好了。

顺便说一下,目前的时尚似乎更倾向于排序(list_)而不是list_.sort(),但排序(list_)是我们在添加它之前没有得到的语言的一个相对新近的补充,它'慢一点。此外,list_.sort()不会像排序(list_)那样引起单行滥用。

哦,香草字典是无序的 - 这就是为什么他们快速访问任意元素(他们构建在哈希表上)的原因。我上面给出的数据结构URL中的一些类型擅长于dict_.find_min()和dict_.find_max()以及obviate keys.sort(),但它们在访问任意元素时速度较慢(logn)。

答案 2 :(得分:1)

您可以对词典的键进行排序并迭代你的词典。

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

OR

在您的情况下,这可能是一种可能的解决方案。我们可以列出所有dictionary's keys列表,其序列不会发生变化,然后我们就可以从您的字典中按顺序获取值。

>>> 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
....

答案 3 :(得分:0)

我不会那样实现它。这很难读。更像是这样:

# 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

...

现在您返回OrderedDict,订单将被保留。不过,我会提醒你。如果确实需要它在某些时候按顺序排列,我会在你需要的时候按正确的顺序排序。不依赖于计算新数据的函数来返回特定排序顺序的内容。在需要排序时排序,而不是之前。