#!/usr/bin/env python # coding: utf-8 # # Idiomatic loops # ## Looping in general # In[ ]: data = ["John", "Doe", "was", "here"] # Don't do it like this. While loops are actually really rarely needed. # In[ ]: idx = 0 while idx < len(data): print(data[idx]) idx += 1 # Don't do like this either. # In[ ]: for idx in range(len(data)): print(data[idx]) # ### Do it like this! # In[ ]: for item in data: print(item) # If you need the index as well, you can use enumerate. # In[ ]: for idx, val in enumerate(data): print(f"{idx}: {val}") # ## Looping over a range of numbers # Don't do this. # In[ ]: i = 0 while i < 6: print(i) i += 1 # Don't do this either. # In[ ]: for val in [0, 1, 2, 3, 4, 5]: print(val) # ### Do it like this! # In[ ]: for val in range(6): print(val) # ## Reversed looping # In[ ]: data = ["first", "to", "last", "from"] # This is no good. # In[ ]: i = len(data) - 1 while i >= 0: print(data[i]) i -= 1 # ### Do it like this! # In[ ]: for item in reversed(data): print(item) # ## Looping over __n__ collections simultaneously # In[ ]: collection1 = ["a", "b", "c"] collection2 = (10, 20, 30, 40, 50) collection3 = ["John", "Doe", True] # Oh boy, not like this. # In[ ]: shortest = len(collection1) if len(collection2) < shortest: shortest = len(collection2) if len(collection3) < shortest: shortest = len(collection3) i = 0 while i < shortest: print(collection1[i], collection2[i], collection3[i]) i += 1 # This is getting better but there's even a better way! # In[ ]: shortest = min(len(collection1), len(collection2), len(collection3)) for i in range(shortest): print(collection1[i], collection2[i], collection3[i]) # ### Do it like this! # In[ ]: for first, second, third in zip(collection1, collection2, collection3): print(first, second, third) # You can also create a dict out of two collections! # In[ ]: my_dict = dict(zip(collection1, collection2)) print(my_dict) # ## `for - else` - Checking for a match in a collection # Let's say we want to verify a certain condition is met by at least one element in a collection. Let's consider the following relatively naive example where we want to verify that at least one item is "python" (case insensitive) in `data`. If not, we'll raise a ValueError. # In[ ]: data = [1, 2, 3, "This", "is", "just", "a", "random", "Python", "list"] # Don't do it like this # In[ ]: found = False for val in data: if str(val).lower() == "python": found = True break if not found: raise ValueError("Nope, couldn't find.") # ### Do it like this! # In[ ]: for val in data: if str(val).lower() == "python": break else: raise ValueError("Nope, couldn't find.")