【问题标题】:Selecting random values from a json file从 json 文件中选择随机值
【发布时间】:2018-10-04 11:03:37
【问题描述】:

我一直在尝试编写一个程序,它会从问题列表中随机选择一个问题,然后显示问题本身。信息存储在.json 文件中。

这是我当前的代码:

import json
import random

with open("C:\\LearningArabic\\LiblibArriby\\Lessons\\L1_Letters\\L1_Letters.json", "r", encoding = "utf-8-sig") as read_file:
    data = json.load(read_file)

t = data["letters"]["part one"]["meem"]["questions"]
print(t) #This prints all of the necessary information. Not actually necessary but it helps me know that this section of code is working
print("")
print(t.get(random.choice(("question"))))
print("")

最终我会进一步完善它,但现在这只是为了让这个想法发挥作用。

这是我的.json 文件:

{"letters":
        {"part one": {
                "meem": {
                        "questions": {
                                "question": "What sound does 'م' make?",
                                "arabic": "م",
                                "transliteration": "m",
                                "english": "m",
                                "answer": "m",
                                "wronganswer" : ["a", "b", "kh", "ta", "da", "du", 

"ee", "yeh", "he", "ha", "l", "n", "f"]},
                        "questions": {
                                "question": "What letters are in the word 'وز'?",   

                                "arabic": "موز",
                                "transliteration": "mooz",
                                "english": "banana",
                                "answer": "م و ز",
                                "wronganswer": [
                                        "ه و ز",
                                        "ه و ر", 
                                        "م ف ز",
                                        "م و ر",
                                        "ه ف ر"]},
                        "questions": {
                                "question": "What word do the letters 'ه ر م' make",    

                                "arabic": "ه ر م",
                                "transliteration": "haram",
                                "english": "pyramid",
                                "answer": "هرم",
                                "wronganswer": [
                                        "مرم", 
                                        "هزم", 
                                        "موم",
                                        "مرع",
                                        "هبم"]}
                        }
                }}
 }

当我运行代码时,我得到以下信息:

{'question': "What word do the letters 'ه ر م' make", 'arabic': 'ه ر م', 'transliteration': 'haram', 'english': 'pyramid', 'answer': 'هرم', 'wronganswer': ['مرم', 'هزم', 'موم', 'مرع', 'هبم']}

None

主要问题:

当我print(t) 时,我想我应该得到所有问题的打印输出。相反,我只得到最后一个问题的打印输出。当我尝试打印一个随机问题时,我得到的结果是“无”,我不明白。我的列表都已填充,为什么 python 找不到任何东西?我的主要目标是学习如何从 json 文件中选择随机值 - 如果我的 json 文件格式需要更新,请告诉我。

【问题讨论】:

  • 这与json 允许重复键有关,但是一旦将其翻译成字典,重复键就会被覆盖,因此只保留最后一个。
  • 那里没有问题列表。
  • @toti08,这是一个重复的问题吗?尽管某些 python 机制可能是相似的(比如我的 .json 文件结构不充分),但我们的问题是要求两个不同的东西。在另一个问题中进行随机选择没有任何意义(这是我的主要观点),如果您想学习如何随机选择元素,那么另一个问题将无济于事 - 特别是对于像我这样的 python 初学者。如果我需要重组我的 .json 文件,那么也许这个问题可以帮助向其他人展示同样的东西。
  • @JackDuane 您说您无法打印所有问题,这是因为您的json 文件中有重复的部分。一旦你解决了这个问题,选择一个随机问题是一个完全不同的问题,与 json 无关,但我认为关键是修复重复的键。

标签: python json python-3.x random


【解决方案1】:

我们不能说 JSON 无效,但您应该避免使用类似的 key 名称(在您的示例中为 questions

RFC 7159 解释了为什么唯一名称(键)是好的:

名称都是唯一的对象在某种意义上是可互操作的 接收该对象的所有软件实现都将同意 名称-值映射。当对象中的名称不是 唯一的,接收这样一个对象的软件的行为是 不可预料的。许多实现报告姓氏/值对 只要。其他实现报告错误或无法解析 对象,一些实现报告所有的名称/值对, 包括重复。

观察到 JSON 解析库在是否或 不是他们使对象成员的顺序对调用可见 软件。行为不依赖于成员的实现 订购将是可互操作的,因为它们不会 受到这些差异的影响。

您可以尝试将您的 JSON 转换为给定的格式:

{
  "letters": {
    "part one": {
      "meem": {
        "questions": [
          {
            "question": "What sound does 'م' make?",
            "arabic": "م",
            "transliteration": "m",
            "english": "m",
            "answer": "m",
            "wronganswer": [
              "a",
              "b",
              "kh",
              "ta",
              "da",
              "du",
              "ee",
              "yeh",
              "he",
              "ha",
              "l",
              "n",
              "f"
            ]
          },
          {
            "question": "What letters are in the word 'وز'?",
            "arabic": "موز",
            "transliteration": "mooz",
            "english": "banana",
            "answer": "م و ز",
            "wronganswer": [
              "ه و ز",
              "ه و ر",
              "م ف ز",
              "م و ر",
              "ه ف ر"
            ]
          },
          {
            "question": "What word do the letters 'ه ر م' make",
            "arabic": "ه ر م",
            "transliteration": "haram",
            "english": "pyramid",
            "answer": "هرم",
            "wronganswer": [
              "مرم",
              "هزم",
              "موم",
              "مرع",
              "هبم"
            ]
          }
        ]
      }
    }
  }
}

然后您可以执行以下操作从问题列表中获取随机问题:

import json
from random import randint


def random_question():
    with open('result.json') as fp:
        data = json.load(fp)
        questions = data["letters"]["part one"]["meem"]["questions"]
        random_index = randint(0, len(questions)-1)
        return questions[random_index]['question']

print(random_question())

输出 What sound does 'م' make? 或者 What letters are in the word 'وز'?

【讨论】:

    【解决方案2】:

    由于您的 JSON 结构包含相同键的多个条目,因此您应该使用自定义 JSON 解码器,通过将相同键的值转换为列表来解决键冲突:

    from json import JSONDecoder
    
    def parse_object_pairs(pairs):
        d = {}
        converted_keys = set()
        for key, value in pairs:
            if key not in d:
                d[key] = value
            elif key in converted_keys:
                d[key].append(value)
            else:
                d[key] = [d[key], value]
                converted_keys.add(key)
        return d
    
    decoder = JSONDecoder(object_pairs_hook=parse_object_pairs)
    data = decoder.decode(read_file.read())
    

    这样data 中的questions 键就变成了一个字典列表:

    {'letters': {'part one': {'meem': {'questions': [{'answer': 'm',
                                                      'arabic': 'م',
                                                      'english': 'm',
                                                      'question': 'What sound does '
                                                                  "'م' make?",
                                                      'transliteration': 'm',
                                                      'wronganswer': ['a',
                                                                      'b',
                                                                      'kh',
                                                                      'ta',
                                                                      'da',
                                                                      'du',
                                                                      'ee',
                                                                      'yeh',
                                                                      'he',
                                                                      'ha',
                                                                      'l',
                                                                      'n',
                                                                      'f']},
                                                     {'answer': 'م و ز',
                                                      'arabic': 'موز',
                                                      'english': 'banana',
                                                      'question': 'What letters '
                                                                  'are in the word '
                                                                  "'وز'?",
                                                      'transliteration': 'mooz',
                                                      'wronganswer': ['ه و ز',
                                                                      'ه و ر',
                                                                      'م ف ز',
                                                                      'م و ر',
                                                                      'ه ف ر']},
                                                     {'answer': 'هرم',
                                                      'arabic': 'ه ر م',
                                                      'english': 'pyramid',
                                                      'question': 'What word do '
                                                                  "the letters 'ه "
                                                                  "ر م' make",
                                                      'transliteration': 'haram',
                                                      'wronganswer': ['مرم',
                                                                      'هزم',
                                                                      'موم',
                                                                      'مرع',
                                                                      'هبم']}]}}}}
    

    这样您就可以轻松地使用列表中的random.choice 来选择要输出的问题:

    print(random.choice(data['letters']["part one"]["meem"]["questions"]))
    

    这个输出(随机):

    {'question': "What sound does 'م' make?", 'arabic': 'م', 'transliteration': 'm', 'english': 'm', 'answer': 'm', 'wronganswer': ['a', 'b', 'kh', 'ta', 'da', 'du', 'ee', 'yeh', 'he', 'ha', 'l', 'n', 'f']}
    

    【讨论】:

    • 不知道为什么您认为我错过了您问题的后半部分,因为我已经向您展示了如何使用random.choice(data['letters']["part one"]["meem"]["questions"]) 打印随机选择的问题字典。只需访问字典的question 键,打印问题本身就变得微不足道了。
    • 我很抱歉。我正要出门上班,但没听清。
    猜你喜欢
    • 1970-01-01
    • 2019-07-30
    • 2012-03-03
    • 2017-03-10
    • 1970-01-01
    • 2014-07-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多