【问题标题】:Parsing key values pairs from text as dictionary将文本中的键值对解析为字典
【发布时间】:2017-11-07 03:17:24
【问题描述】:

我对 Python 还是很陌生,我想知道如何将文本文件中已经采用 key:value 形式的内容转换为 Python 字典?

例如。

2:red 
3:orange 
5:yellow 
6:green 

(每个键:单独一行的值)

我查看了其他帖子,但它们似乎都不起作用,我知道我做错了什么。到目前为止,我有:

def create_colours_dictionary(filename):
    colours_dict = {}
    file = open(filename,'r')
    contents = file.read()

    for key in contents:
        #???
    return colours_dict

【问题讨论】:

    标签: python file dictionary


    【解决方案1】:

    遍历您的文件并构建字典。

    def create_colours_dictionary(filename):
        colours_dict = {}
        with open(filename) as file:
            for line in file:
                k, v = line.rstrip().split(':')
                colours_dict[k] = v
    
        return colours_dict
    
    dct = create_colours_dictionary('file.txt')
    

    或者,如果您正在寻找紧凑的东西,您可以使用带有 lambda 的 dict 推导式来拆分冒号。

    colours_dict = {k : v for k, v in (
        line.rstrip().split(':') for line in open(filename)
    }
    

    如果冒号被空格包围,这种方法需要一些修改——也许是正则表达式?

    【讨论】:

    • 对每个x 调用两次x.split(':') 有点低效。此外,这个算法有点脆弱:如果分隔符不完全是':',即如果有任何中间空格,它将失败。
    • @PM2Ring 我同意。但是解决这个问题需要一个循环而不是理解。前者不是更具pythonic和可读性吗?分隔符完全基于 OP 的问题。
    • 当然,使用':' 分隔符是可以的,但还是要提一下,如果冒号周围有空格,该算法将不起作用。
    • 使用推导式不一定更 Pythonic:如果它比传统的 for 循环解决方案效率低,那么最好使用传统的循环。但是,有几种方法可以避免双重 .split 调用。
    • @PM2Ring 有道理。由于您已经探索了其他方法,因此我将保持原样回答。
    【解决方案2】:

    执行此操作的直接方法是使用传统的for 循环和str.split 方法。

    我不会从文件中读取,而是将输入数据作为多行字符串嵌入到脚本中,并使用str.splitlines 将其转换为字符串列表,这样我们就可以循环遍历它,就像循环遍历文件的行。

    # Use a list of strings to simulate the file
    contents = '''\
    2:red
    3:orange
    5:yellow
    6:green
    '''.splitlines()
    
    colours_dict = {}
    for s in contents:
        k, v = s.split(':')
        colours_dict[k] = v
    
    print(colours_dict) 
    

    输出

    {'2': 'red', '3': 'orange', '5': 'yellow', '6': 'green'}
    

    请注意,只有在冒号周围没有空格时,此代码才能正常工作。如果可能有空格(或行首或行尾的空格),您可以使用str.strip 方法将其删除。


    有几种方法可以使它更紧凑。

    我们可以使用嵌套在字典推导中的列表推导:

    colours_dict = {k: v for k, v in [s.split(':') for s in contents]}
    

    但是在generator expression 上使用dict 构造函数更加紧凑:

    colours_dict = dict(s.split(':') for s in contents)
    

    如果您不熟悉推导式,请参阅 List ComprehensionsDictionaries在官方教程中。

    【讨论】:

      【解决方案3】:

      假设文本文件具有指定的“键:值”并且文件的名称包含在变量fname 中,您可以编写一个函数来读取文件并返回dict,或者只使用简单的@ 987654323@ 声明。

      如果在代码中的多个位置执行此操作,则函数可能是更好的选择。如果只做一次 2-liner 就可以了。

          # Example with fname being the path to the textfile
          def dict_from(fname):
              return dict(line.strip().split(':') for line in open(fname))
      
          fname = '...'
          # ...
          d1 = dict_from(fname)
      
          # Alternative solution
          with open(fname) as fd:
             d2 = dict(line.strip().split(':') for line in fd)
      

      两种建议的解决方案都使用内置的dictconstructor 和生成器表达式来解析每一行。使用strip 删除行首和行尾的空白。使用 split 从每一行创建一个 (key, value) 对。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2023-03-15
        • 2020-03-31
        • 2012-11-08
        • 1970-01-01
        • 2017-08-24
        • 2017-07-21
        • 2018-10-12
        • 1970-01-01
        相关资源
        最近更新 更多