How to exit from a double loop in a pythonic way?
yellow = ['255', '255', '0'] for row in range(50): for col in range(50): pixel = data[row][col] if pixel == yellow: upper_left = (row, col) break When pixel is yellow, how should be this loop terminated? Now it continues with the outer loop again which is not desired.
2/12/2020 7:02:56 PMProf. Dr. Zoltán Vass
27 AnswersNew Answer
for row in range(50): for col in range(50): pixel = data[row][col] if pixel == yellow: upper_left = (row, col) break else: continue break if second loop breaks then first loop breaks too
The use of itertools.product or a function with return to terminate both loops that you already mentioned seem nice and concise, if that is what Pythonic means.
On another note, would it be better (or more Pythonic) to use a tuple rather than a list to represent each colour, as the number of colour components is always constant(3) and doesn't grow?
Prof. Dr. Zoltán Vass the short answer is the condition pixel == yellow Will NEVER comes through and you won't be able to exit the loop, saying pixel is a matrix...a matrix of integers while yellow is a list of strings
I would have also used a control flag(boolean variable) to terminate the outer loop but I guess it's not that Pythonic.
guillem ardanuy flag = False for i in range(8): for j in range(8): if whatever: flag = True break if flag: break This is what I called C-ish. If I knew a shorter, *easily readable* technique, I would choose it. Maybe it's also a bit a matter of getting used to the pattern else break
Gabriel Ilie Another solution, seems to me more pythonic: def find_yellow(): for raw in range(50): for col in range(50): if data[raw][col] == yellow: return (raw, col) upper_left = find_yellow()
guillem ardanuy Many people use a boolean flag as control variable but the code is longer, eg: found = False while not found: for row in range(50): for col in range(50): pixel = data[row][col] if pixel == yellow: upper_left = (row, col) found = True break if found: break
guillem ardanuy Mirielle👽 For me, this 4-liner seems to be the most pythonic: from itertools import product for row, col in product(range(50), range(50)): if data[row][col] == ['255', '255', '0']: break
Mirielle👽 Thanks for your comment and sorry for my unclear or uncomplete question. The code actually works because the list is a matrix of strings, eg. [[[‘0’, ‘0’, ‘0’], [‘0’, ‘0’, ‘0’]...]]. In this way, list items can be matched the variable yellow, eg: data # it is ['255', '255', '0'] yellow = ['255', '255', '0'] so data == yellow is True
Sonic “Pythonic” is somewhat subjective but there are guidelines, ie. The Zen of Python or PEP8. “Exploiting the features of the Python language to produce code that is clear, concise and maintainable. Pythonic means code that doesn't just get the syntax right but that follows the conventions of the Python community and uses the language in the way it is intended to be used.” https://stackoverflow.com/questions/25011078/what-does-pythonic-mean
HonFu You are very advanced. Which solution would you prefer for exiting double loops?
guillem ardanuy Just a quick tipp: you can try to use the @ sign before usernames.
depends on your definition for the term "pythonic" I don't think there's something else more pythonic than "break" in a forloop Prof. Dr. Zoltán Vass Note that a "if statement" will work only if the condition is true if pixel == yellow yellow must be an assigned variable and before the loops stop, pixel must be equals to it's value
Mirielle👽 Thanks, Mirielle. How to break the first loop (row) when yellow is found?
Prof. Dr. Zoltán Vass yellow can never be found because it's a list and you're comparing a string with it
Mirielle👽 Actually, this list is a matrix of strings, eg. [[[‘0’, ‘0’, ‘0’], [‘0’, ‘0’, ‘0’]...]] which represents an 50x50 image’s RGB pixels
Gabriel Ilie Yes, this works!
🤣 double loop is double loop🧐🧐 You might hide it through some syntactic sugar... Double loop stays double loop
from itertools import product for row, col in product(range(50), range(50)): if data[row][col] == ['255', '255', '0']: upper_left = (row, col) break