【问题标题】:Python 3.8 dictionary value sorting alphabeticallyPython 3.8 字典值按字母顺序排序
【发布时间】:2020-02-12 10:28:16
【问题描述】:

此代码用于读取文本文件并将每个单词添加到字典中,其中键是第一个字母,值是文件中以该字母开头的所有单词。它有点工作,但对于 我遇到了两个问题:

  1. 字典键包含撇号和句号(如何排除?)
  2. 这些值不是按字母顺序排列的,而且都是乱七八糟的。代码最终输出如下内容:
' - {"don't", "i'm", "let's"}
. - {'below.', 'farm.', 'them.'}
a - {'take', 'masters', 'can', 'fallow'}
b - {'barnacle', 'labyrinth', 'pebble'}
...
...
y - {'they', 'very', 'yellow', 'pastry'}

什么时候应该更像:

a - {'ape', 'army','arrow', 'arson',}
b - {'bank', 'blast', 'blaze', 'breathe'}
etc
# make empty dictionary
dic = {}

# read file
infile = open('file.txt', "r")

# read first line
lines = infile.readline()
while lines != "":
    # split the words up and remove "\n" from the end of the line
    lines = lines.rstrip()
    lines = lines.split()

    for word in lines:
        for char in word: 
            # add if not in dictionary
             if char not in dic: 
                dic[char.lower()] = set([word.lower()])
            # Else, add word to set
             else:
                dic[char.lower()].add(word.lower())
    # Continue reading
    lines = infile.readline()

# Close file
infile.close()

# Print
for letter in sorted(dic): 
    print(letter + " - " + str(dic[letter]))

我猜我在第一次遍历文件时需要从整个文件中删除标点符号和撇号,但在向字典中添加任何内容之前?但是,在以正确的顺序获取值时完全迷失了。

【问题讨论】:

  • 问题是你正在遍历单词中的每个字符,然后将单词添加到该键中。只需取第一个字符,即word[0],然后检查它是否为.isalpha()
  • 注意,永远不要像那样循环文件,文件对象是文件中行的迭代器,所以你可以这样做for line in infile: ...

标签: python dictionary set


【解决方案1】:

在删除任何起始标点符号后使用defaultdict(set)dic[word[0]].add(word)。不需要内循环。

【讨论】:

    【解决方案2】:
    from collections import defaultdict
    
    
    def process_file(fn):
        my_dict = defaultdict(set)
        for word in open(fn, 'r').read().split():
            if word[0].isalpha():
                my_dict[word[0].lower()].add(word)
        return(my_dict)
    
    
    word_dict = process_file('file.txt') 
    for letter in sorted(word_dict): 
        print(letter + " - " + ', '.join(sorted(word_dict[letter])))
    

    【讨论】:

      【解决方案3】:

      你有很多问题

      1. 在空格和标点符号上分割单词
      2. 将单词添加到第一次添加时不存在的集合中
      3. 对输出进行排序

      这是一个尝试解决上述问题的小程序

      import re, string
      
      # instead of using "text = open(filename).read()" we exploit a piece
      # of text contained in one of the imported modules
      text = re.__doc__
      
      # 1. how to split at once the text contained in the file
      #
      # credit to https://stackoverflow.com/a/13184791/2749397
      p_ws = string.punctuation + string.whitespace
      words = re.split('|'.join(re.escape(c) for c in p_ws), text)
      
      # 2. how to instantiate a set when we do the first addition to a key,
      #    that is, using the .setdefault method of every dictionary
      d = {}
      # Note: words regularized by lowercasing, we skip the empty tokens    
      for word in (w.lower() for w in words if w):
          d.setdefault(word[0], set()).add(word)
      
      # 3. how to print the sorted entries corresponding to each letter
      for letter in sorted(d.keys()):
          print(letter, *sorted(d[letter]))
      

      我的text 包含数字,因此可以在上述程序的输出(见下文)中找到数字;如果你不想用数字过滤它们,if letter not in '0123456789': print(...)

      这是输出...

      0 0
      1 1
      8 8
      9 9
      a a above accessible after ailmsux all alphanumeric alphanumerics also an and any are as ascii at available
      b b backslash be before beginning behaviour being below bit both but by bytes
      c cache can case categories character characters clear comment comments compatibility compile complement complementing concatenate consist consume contain contents corresponding creates current
      d d decimal default defined defines dependent digit digits doesn dotall
      e each earlier either empty end equivalent error escape escapes except exception exports expression expressions
      f f find findall finditer first fixed flag flags following for forbidden found from fullmatch functions
      g greedy group grouping
      i i id if ignore ignorecase ignored in including indicates insensitive inside into is it iterator
      j just
      l l last later length letters like lines list literal locale looking
      m m made make many match matched matches matching means module more most multiline must
      n n name named needn newline next nicer no non not null number
      o object occurrences of on only operations optional or ordinary otherwise outside
      p p parameters parentheses pattern patterns perform perl plus possible preceded preceding presence previous processed provides purge
      r r range rather re regular repetitions resulting retrieved return
      s s same search second see sequence sequences set signals similar simplest simply so some special specified split start string strings sub subn substitute substitutions substring support supports
      t t takes text than that the themselves then they this those three to
      u u underscore unicode us
      v v verbose version versions
      w w well which whitespace whole will with without word
      x x
      y yes yielding you
      z z z0 za
      

      没有 cmets 和一点混淆,它只是 3 行代码......

      import re, string
      text = re.__doc__
      p_ws = string.punctuation + string.whitespace
      words = re.split('|'.join(re.escape(c) for c in p_ws), text)
      
      d, add2d = {}, lambda w: d.setdefault(w[0],set()).add(w) #1
      for word in (w.lower() for w in words if w): add2d(word) #2
      for abc in sorted(d.keys()): print(abc, *sorted(d[abc])) #3
      

      【讨论】:

        猜你喜欢
        • 2019-12-24
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-01-26
        • 1970-01-01
        • 2015-12-09
        相关资源
        最近更新 更多