<jupyter_start><jupyter_text>Item 17: Be Defensive When Iterating Over Arguments Be careful when passing iterator around<jupyter_code>a = [1 ,2 ,3 ,4]
iterator = (b**2 for b in a)

print(sum(iterator))
print(sum(iterator))<jupyter_output>30
0<jupyter_text>Once the iterator is exhausted, it does not return anyting. This happens silenty and can result in bugs, especially if the exhaust happens somewhere deep inside the code.  Some workarounds:* Instead of parsing the iterator, pass the function which returns it<jupyter_code># Passing the function that returns the itertator
def get_iter(a):
    return (b**2 for b in a)
print(sum(get_iter(a)))
print(sum(get_iter(a)))

# Defining own iteratble

class hi:
    
    def __init__(self):
        pass
        
    def __iter__(self):
        for idx in range(5):
            yield "hi "*idx

hey = hi()

for string in hey:
    print(string)<jupyter_output>hi 
hi hi 
hi hi hi 
hi hi hi hi
{'fraction_non_alphanumeric': 0.08635394456289978, 'fraction_numerical': 0.01279317697228145, 'mean_word_length': 3.942105263157895, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 7, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '2', 'dir': 'jupyter-structured-clean-dedup', 'id': '326584', 'license': 'MIT', 'n_tokens_mistral': 313, 'n_tokens_neox': 306, 'n_words': 117, 'path': 'notes/Chapter_2:_Functions/Item 17 Be Defensive When Iterating Over Arguments.ipynb', 'repo_name': 'johannstruongle/effective_python', 'size': '938'}