Reputation: 33
I'm trying to iterate through a JSON file to search for specific parts and print out that portion of the file. But my code only works for the first dict in the file, anything past that will have my code print out that the part of the JSON file doesn't exit. Here is the JSON file:
[
{
"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"
}
]
Here is my Code:
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
So say I enter the name "Debian" I get the version number just fine. But if I type in "Fedora" for example, I get the "Title not found" portion of my code. Which means that the name wasn't in the JSON file but it is. Any help would be appreciated.
Upvotes: 2
Views: 66
Reputation: 29317
With break
you're exiting immediately the for loop as soon as one element doesn't match name, hence the code works only for the first match.
This is how one could write a loop with a break statement
found = False
for i in obj:
if i["Name"] == name:
found = True
break
if found:
print(i["Version"])
else:
print("Title not found")
If the loop is inside a function you could simply use return
in place of break
def search(obj, name):
for i in obj:
if i["Name"] == name:
return i["Version"]
return "Title not found"
But the pythonic way to implement this would be:
next((i["Version"] for i in iter(obj) if i["Name"] == name), "Title not found")
next
will stop after the first match as well.
Example:
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'
Upvotes: 0
Reputation: 923
Your loop always ends on the first iteration.
Corrected version:
# ...
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
Upvotes: 0
Reputation: 16772
For the sake of simplicity:
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"
}
]
Using list-comprehension
:
search = 'Fedora'
print([x['Version'] for x in s if x['Name'] == search])
OUTPUT:
['26']
Explanation:
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
Upvotes: 1