Не могу пройти первый Dict в файле JSON - PullRequest
1 голос
/ 20 апреля 2019

Я пытаюсь перебрать JSON-файл, чтобы найти определенные детали и распечатать эту часть файла. Но мой код работает только для первого вхождения в файле, и все, что осталось после того, как мой код будет распечатан, часть файла JSON не завершится. Вот файл JSON:

[
{
    "Name": "Debian",
    "Version": "9",
    "Install": "apt",
    "Owner": "SPI",
    "Kernel": "4.9"
},
{
    "Name": "Ubuntu",
    "Version": "17.10",
    "Install": "apt",
    "Owner": "Canonical",
    "Kernel": "4.13"
},
{
    "Name": "Fedora",
    "Version": "26",
    "Install": "dnf",
    "Owner": "Red Hat",
    "Kernel": "4.13"
},
{
    "Name": "CentOS",
    "Version": "7",
    "Install": "yum",
    "Owner": "Red Hat",
    "Kernel": "3.10"
},
{
    "Name": "OpenSUSE",
    "Version": "42.3",
    "Install": "zypper",
    "Owner": "Novell",
    "Kernel": "4.4"
},
{
    "Name": "Arch Linux",
    "Version": "Rolling Release",
    "Install": "pacman",
    "Owner": "SPI",
    "Kernel": "4.13"
},
{
    "Name": "Gentoo",
    "Version": "Rolling Release",
    "Install": "emerge",
    "Owner": "Gentoo Foundation",
    "Kernel": "4.12"
}

]

Вот мой код:

import json

jsonfile = raw_input("Choose a json file: ")
type(jsonfile)

name = input("Type in the name: ")
type(name)

with open (jsonfile) as myfile:
   data = myfile.read()

obj = json.loads(data)

for i in obj:
  if i["Name"] == name:
     print(i["Version"])
     break
  else:
     print("Title not found")
     break

Скажем, я ввожу имя "Debian", я получаю номер версии просто отлично. Но если я наберу "Fedora", например, я получу часть "Заголовок не найден" в моем коде. Это означает, что имя не было в файле JSON, но оно есть. Любая помощь будет оценена.

Ответы [ 3 ]

1 голос
/ 21 апреля 2019

Ради простоты:

s = [
      {
        "Name": "Debian",
        "Version": "9",
        "Install": "apt",
        "Owner": "SPI",
        "Kernel": "4.9"
      },
      {
        "Name": "Ubuntu",
        "Version": "17.10",
        "Install": "apt",
        "Owner": "Canonical",
        "Kernel": "4.13"
      },
      {
        "Name": "Fedora",
        "Version": "26",
        "Install": "dnf",
        "Owner": "Red Hat",
        "Kernel": "4.13"
      },
      {
        "Name": "CentOS",
        "Version": "7",
        "Install": "yum",
        "Owner": "Red Hat",
        "Kernel": "3.10"
      },
      {
        "Name": "OpenSUSE",
        "Version": "42.3",
        "Install": "zypper",
        "Owner": "Novell",
        "Kernel": "4.4"
      },
      {
        "Name": "Arch Linux",
        "Version": "Rolling Release",
        "Install": "pacman",
        "Owner": "SPI",
        "Kernel": "4.13"
      },
      {
        "Name": "Gentoo",
        "Version": "Rolling Release",
        "Install": "emerge",
        "Owner": "Gentoo Foundation",
        "Kernel": "4.12"
      }
]

Использование list-comprehension:

search = 'Fedora'

print([x['Version'] for x in s if x['Name'] == search])

OUTPUT

['26']

Объяснение

search = 'Fedora'

for elem in s:                      # for each elem in the list
    if elem['Name'] == search:      # check if the Name is what you're looking for
        print(elem['Version'])      # print the Version if it is

OUTPUT

26
0 голосов
/ 21 апреля 2019

С break вы немедленно выходите из цикла for, как только один элемент не соответствует имени, следовательно, код работает только для первого соответствия.

Вот как можно написать цикл с помощью оператора break

found = False
for i in obj:
    if i["Name"] == name:
        found = True
        break

if found:
    print(i["Version"])
else:
    print("Title not found")

Если цикл находится внутри функции, вы можете просто использовать return вместо break

def search(obj, name):
    for i in obj:
        if i["Name"] == name:
            return i["Version"]
    return "Title not found"

Но питонский способ реализовать это будет следующим:

next((i["Version"] for i in iter(obj) if i["Name"] == name), "Title not found")

next остановится и после первого матча.

Пример:

obj= [
{
    "Name": "Debian",
    "Version": "9"
},
{
    "Name": "Ubuntu",
    "Version": "17.10"
},
{
    "Name": "Fedora",
    "Version": "26"
}]

name = "Fedora" 
next((i["Version"] for i in iter(obj) if i["Name"] == name), "Title not found")
# Out:
# '26'
0 голосов
/ 21 апреля 2019

Ваш цикл всегда заканчивается на первой итерации.
Исправленная версия:

# ...
for i in obj:
    if i["Name"] == name:
        print(i["Version"])
        break
else:
    print("Title not found")

http://book.pythontips.com/en/latest/for_-_else.html

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...