I'm new to python programming. I have tried a lot to avoid these nested for loops, but no success.
My data input like:
[
{
"province_id": "1",
"name": "HCM",
"districts": [
{
"district_id": "1",
"name": "Thu Duc",
"wards": [
{
"ward_id": "1",
"name": "Linh Trung"
},
{
"ward_id": "2",
"name": "Linh Chieu"
}
]
},
{
"district_id": "2",
"name": "Quan 9",
"wards": [
{
"ward_id": "3",
"name": "Hiep Phu"
},
{
"ward_id": "4",
"name": "Long Binh"
}
]
}
]
},
{
"province_id": "2",
"name": "Binh Duong",
"districts": [
{
"district_id": "3",
"name": "Di An",
"wards": [
{
"ward_id": "5",
"name": "Dong Hoa"
},
{
"ward_id": "6",
"name": "Di An"
}
]
},
{
"district_id": "4",
"name": "Thu Dau Mot",
"wards": [
{
"ward_id": "7",
"name": "Hiep Thanh"
},
{
"ward_id": "8",
"name": "Hiep An"
}
]
}
]
}
]
And my code is:
for province in data:
for district in province['districts']:
for ward in district['wards']:
# Excute my function
print('{}, {}, {}'.format(ward['name'], district['name'], province['name']))
Output
Linh Trung, Thu Duc, HCM
Linh Chieu, Thu Duc, HCM
Hiep Phu, Quan 9, HCM
...
Even though my code is working it looks pretty ugly.
How can I avoid these nested for loops?
The syntax for nesting while loop in Python is: while (expression_1): #Outer loop [code to execute] #Optional while (expression_2): #Inner loop [code to execute] Unlike the for loop, the while loop doesn’t have a precompiled iterable sequence. While loop keeps executing the code until the expression evaluates to true.
Nested loops are not a bad thing per se. They are only bad, if there are used for problems, for which better algorithm have been found (better and bad in terms of efficiency regarding the input size). Sorting of a list of integers for example is such a problem. In your case above you have three lists, all of size 4.
In Python, when the continue statement is encountered inside the loop, it skips all the statements below it and immediately jumps to the next iteration. In the following example, we have two loops. The outer for loop iterates the first list, and the inner loop also iterates the second list of numbers.
Python can’t do this, but others can, such as the PHP: In PHP, the break keyword accepts an optional number which determines how many nested loops are to be broken out of. The default value is 1, which means to break out of the inner-most loop. It’s a very neat and clear solution.
Your data structure is naturally nested, but one option you have for neatening your code is to write a generator function for iterating over it:
def all_wards(data):
for province in data:
for district in province['districts']:
for ward in district['wards']:
yield province, district, ward
This function has the same triply-nested loop in it as you currently have, but everywhere else in your code, you can now iterate over the data structure with a single non-nested loop:
for province, district, ward in all_wards(data):
print('{}, {}, {}'.format(ward['name'], district['name'], province['name']))
If you prefer to avoid having too much indentation, here's an equivalent way to write the function, similar to @adarian's answer but without creating a temporary list:
def all_wards(data):
return (
province, district, ward
for province in data
for district in province['districts']
for ward in district['wards']
)
Here is a one-liner version
[
print("{}, {}, {}".format(ward["name"], district["name"], province["name"]))
for province in data
for district in province["districts"]
for ward in district["wards"]
]
You could do something like this:
def print_district(district, province):
for ward in district['wards']:
print('{}, {}, {}'.format(ward['name'], district['name'], province['name']))
def print_province(province):
for district in province['districts']:
print_district(district, province)
for province in data:
print_province(province)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With