【问题标题】:Read a file and insert content to dictionaries读取文件并将内容插入字典
【发布时间】:2017-11-28 08:44:10
【问题描述】:

我有一个包含餐馆信息的文本文件,需要将这些信息插入到几个字典中。属性是名称、评级、价格范围、美食类型

这是txt的内容

Georgie Porgie 
87% 
$$$ 
Canadian,Pub Food

Queen St. Cafe 
82% 
$ 
Malaysian,Thai

到目前为止,我已经阅读了文件并将内容抓取到一个列表中。

content = [];
with open(file) as f:
        content = f.readlines();
        content = [x.strip() for x in content];

需要插入三个字典 names_rating,price_names,cuisine_names 我该怎么做?

【问题讨论】:

  • 您必须提供更多信息。具体来说,有人需要知道字典的结构才能给出问题的完整答案。
  • 您的输入与您在示例中给出的完全一样,还是逗号分隔?在前一种情况下,您的主要问题是找到分割每一行的位置,以便在每个字典中获取正确的数据。
  • 为什么不尝试直到出现错误并且无法解决?
  • 你在for循环中声明的line变量已经有了你想要的行,你应该使用它而不是使用f.readline()
  • 您提供的代码可能无法生成有用的列表。 [x for x in some_string] 将生成some_string 中的字符列表,这可能不是您的想法。

标签: python file dictionary


【解决方案1】:

一般来说,要从列表列表list_of_lists 构建字典列表lists_of_dicts,您将索引i 处的项目映射到索引j 处的项目,您将使用字典像这样比较:

list_of_dicts = {lst[i]: lst[j] for lst in list_of_lists}

您应该能够将其应用于任意list_of_lists 以解决您的问题。

【讨论】:

  • i & j 声明在哪里?
  • 它们在设置中给出,list_of_lists
【解决方案2】:

鉴于您对文本文件的最新格式规范:

Georgie Porgie 
87% 
$$$ 
Canadian,Pub Food

Queen St. Cafe 
82% 
$ 
Malaysian,Thai

如果你可以假设:

  • 每个餐厅条目将始终由四行定义,每行包含您所关注的字段(阅读:字典条目)
  • 字段将始终以完全相同的顺序出现
  • 每个条目将始终通过空行与下一个条目分隔

那么您可以使用modulo operation 并执行以下操作:

import re

content = {}
filepath = 'restaurants_new.txt'
with open(filepath, 'r') as f:
    fields = ['name', 'rating', 'price', 'cuisine']
    name = ''
    for i, line in enumerate(f):
        modulo = i % 5
        raw = line.strip()
        if modulo == 0:
            name = raw
            content[name] = {}
        elif modulo < 4:
             content[name][fields[modulo]] = raw
        elif modulo == 4:
            # we gathered all the required info; reset
            name = ''

from pprint import pformat
print pformat(content)

编辑: 在您最初发布的格式之后提出了以下解决方案,如下所示:

Georgie Porgie 87% $$$ Canadian,Pub Food
Queen St. Cafe 82% $ Malaysian,Thai

我把原来的答案留在这里,以防它对其他人仍然有用。

作为JohanL mentioned in his comment,解决您的问题的最重要的一点是行格式:取决于您是否使用逗号或空格作为分隔符,或者两者兼而有之,并考虑到餐厅的名称可能包含未知数单词,找到如何拆分行可能会变得很棘手。

这是一种与@gaurav 建议的方法略有不同的方法,使用regular expressionsre 模块):

import re

content = {}
filepath = 'restaurants.txt'
dictmatch = r'([\s\S]+) ([0-9]{1,3}\%) (\$+) ([\s\S]+)'
with open(filepath, 'r') as f:
    for line in f:
        raw = line.strip()
        match = re.match(dictmatch, raw)
        if not match:
            print 'no match found; line skipped: "%s"' % (raw, )
            continue
        name = match.group(1)
        if name in content:
            print 'duplicate entry found; line skipped: "%s"' % (raw, )
            continue
        content[name] = {
            "rating": match.group(2),
            "price": match.group(3),
            "cuisine": match.group(4) 
        }

from pprint import pformat
print pformat(content)

假设您无法控制源 txt,此方法的优点是您可以定制正则表达式模式以匹配它附带的任何“非最佳”格式。

【讨论】:

    【解决方案3】:

    看到你给出的文件示例,元素是空格分隔的。

    所以,你的任务是:

    • 打开文件
    • 阅读每一行
    • 用空格分割条目
    • 将条目保存在字典中

    这将按如下方式完成:

    names_rating = {}
    price_names = {}
    cuisine_names = {}
    with open(file) as f:
        lines = []
        for line in f:
            content = f.readline().rstrip()
            if content != ''
                lines.append(content)
            if len(lines) > 4 :
                name = lines[0]
                rating = lines[1]
                price = lines[2]
                cuisine = lines[3].split(',')
                names_rating[name] = rating
                price_names[name] = price
                cuisine_name[name] = cuisine
                lines = []
    

    在此,逐行读取文件并将结果附加到列表lines 中。当列表大小超过 4 时,将所有属性读入列表。然后对它们进行处理以将数据保存在字典中。然后列表被清空以再次执行该过程。

    【讨论】:

    • 我所有的文件内容都在内容数组中。
    • @KumaranathFernando 从文件中读取的每一行都保存为string 变量而不是list。所以content 变量不能是list。这是一个string。尾随换行符\n 也被读入变量。 rstrip() 函数可用于strings 以删除不必要的尾随字符。我已经根据this对代码进行了更正。
    • 我的错,我在文本内容上犯了错误。每个属性不打算用空格分隔,而是用换行符
    • @KumaranathFernando 在这种情况下,你可以轻松地一一读取 4 行并将它们保存在 namesratingpricecuisine 变量中,其余保持不变
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-11-02
    • 1970-01-01
    • 1970-01-01
    • 2022-01-14
    • 2023-03-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多