1
votes

Impossible de dépasser le premier dict dans le fichier JSON

J'essaie de parcourir un fichier JSON pour rechercher des parties spécifiques et imprimer cette partie du fichier. Mais mon code ne fonctionne que pour le premier dict du fichier, tout ce qui est passé qui affichera mon code indiquant que la partie du fichier JSON ne se ferme pas. Voici le fichier JSON:

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

]

Voici mon code:

[
{
    "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"
}

Alors dis que j'entre le name "Debian" Je reçois très bien le numéro de version. Mais si je tape "Fedora" par exemple, j'obtiens la partie "Titre non trouvé" de mon code. Ce qui signifie que le nom n'était pas dans le fichier JSON, mais c'est le cas. Toute aide serait appréciée.


2 commentaires

C'est une liste de dict, pour chaque élément de la liste, itérer sur la clé, val et vérifier la clé.


PS. Si le premier élément n'est pas ce que vous recherchez, l'instruction break ne vérifie pas le reste. par conséquent, il échoue.


3 Réponses :


1
votes

Par souci de simplicité:

26

Utilisation de list-comprehension:

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']

Explication :

search = 'Fedora'

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

OUTPUT :

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"
      }
]


1 commentaires

Merci pour l'explication, cela fonctionne très bien.



0
votes

Votre boucle se termine toujours à la première itération.
Version corrigée:

# ...
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


0 commentaires

0
votes

Avec break , vous quittez immédiatement la boucle for dès qu'un élément ne correspond pas au nom, donc le code ne fonctionne que pour la première correspondance.

Voici comment écrire une boucle avec une instruction break

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'

Si la boucle est à l'intérieur d'une fonction, vous pouvez simplement utiliser return dans lieu de break

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

Mais la manière pythonique de l'implémenter serait:

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

next s'arrêtera après le premier match également.

Exemple:

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

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


0 commentaires