<jupyter_start><jupyter_text>A simple implementation of an iterator mimicking Python's range() function. myrange(), however, starts counting at one, while range() starts a zero.<jupyter_code>class myrange:
    def __init__(self, n):
        self.n = n
        self.i = 0

    def __iter__(self):
        return self

    def __next__(self):
        self.i += 1
        if self.i > self.n:
            raise StopIteration
        return self.i

    def __getitem__(self, item):
        return item + 1

    def __len__(self):
        return self.n
for i in myrange(3):
    print(i)<jupyter_output>1
2
3<jupyter_text>Just for fun, a simple generator (actually an iterator) for keys. The interesting part here is, that the iterator is infinite. No StopIteration exception is raised.<jupyter_code>class KeyGen:  
    def __init__(self, charset, k):
        self.charset = charset
        self.k = k

    def __next__(self):
        from random import choices
        return ''.join(choices(self.charset, k=self.k))

    def __iter__(self):
        return self
users = ['Stef', 'John', 'Jane']
keys = KeyGen('ABCDabcd_!$', 5)
for user, key in zip(users, keys):
    print(user, ':', key)<jupyter_output>Stef : _Cc_C
John : $bb!c
Jane : B_B_!<jupyter_text>A reader for FASTA files. Implemented as an Iterator with Context Management (__enter__(), __exit__()) to autmatically close the file.<jupyter_code>class FastaReader:
    def __init__(self, filepath):
        self.filepath = filepath

    def __next__(self):
        nextline = lambda: next(self.lines).strip()
        header = nextline()
        seq = ''.join(iter(nextline, ''))
        return header, seq

    def __iter__(self):
        return self

    def __enter__(self):
        self.lines = open(self.filepath)
        return self

    def __exit__(self, *exc):
        self.lines.close()
with FastaReader('sequences.fa') as reader:
    for header, seq in reader:
        print('header:', header)
        print('seq   :', seq)
        print()<jupyter_output>header: ;LCBO - Prolactin precursor - Bovine
seq   : MDSKGSSQKGSRLLLLLVVSNLLLCQGVVSTPVCPNGPGNCQVSLRDLFDRAVMVSHYIHDLSSEMFNEFDKRYAQGKGFITMALNSCHTSSLPTPEDKEQAQQTHHEVLMSLILGLLRSWNDPLYHLVTEVRGMKGAPDAILSRAIEIEEENKRLLEGMEMIFGQVIPGAKETEPYPVWSGLPSLQTKDEDARYSAFYNLLHCLRRDSSKIDTYLKLLNCRIIYNNNC*

header: >MCHU - Calmodulin - Human, rabbit, bovine, rat, and chicken
seq   : MADQLTEEQIAEFKEAFSLFDKDGDGTITTKELGTVMRSLGQNPTEAELQDMINEVDADGNGTIDFPEFLTMMARKMKDTDSEEEIREAFRVFDKDGNGYISAAELRHVMTNLGEKLTDEEVDEMIREADIDGDGQVNYEEFVQMMTAK*

header: >gi|5524211|gb|AAD44166.1| cytochrome b [Elephas maximus maximus]
seq   : LCLYTHIGRNIYYGSYLYSETWNTGIMLLLITMATAFMGYVLPWGQMSFWGATVITNLFSAIPYIGTNLVEWIWGGFSVDKATLNRFFAFHFILPFTMVALAGVHLTFLHETGSNNPLGLTSDSDKIPFHPYYTIKDFLGLLILILLLLLLALLSPDMLGDPDNHMPADPLNTPLHIKPEWYFLFAYAILRSVPNKLGGVLALFLSIVILGLMPFLHTSKHRSMMLRPLSQALFWTLTMDLLTLTWIGSQPVEYPYTIIGQMASILYFSIILAFLPIAGXIENY<jupyter_text>In the following some examples for common Iterator functions.<jupyter_code>enumerate('abc')   # iterators are lazy and don't do anything until next is called!
for i,c in enumerate('abc'):
    print(i,c)
''.join(reversed('abc'))
it = iter([0, 1 ,2, 3, 4, 5])
tuple(zip(it, it))
nums = [0, 1 ,2, 3, 4]
list(map(str, nums))
nums = [0, 1 ,2, 3, 4]
gt2 = lambda x: x > 2
list(filter(gt2, nums))
list(map(str, filter(gt2, nums)))
Making a chain of iterators more readable by using nutsflow (https://maet3608.github.io/nuts-flow/)
from nutsflow import *

nums >> Filter(gt2) >> Map(str) >> Collect()<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.10107587768969423, 'fraction_numerical': 0.013023782559456399, 'mean_word_length': 4.210914454277286, 'pattern_counts': {'":': 0, '<': 14, '<?xml version=': 0, '>': 24, 'https://': 1, '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': '4', 'dir': 'jupyter-structured-clean-dedup', 'id': '485455', 'license': 'Apache-2.0', 'n_tokens_mistral': 1415, 'n_tokens_neox': 1325, 'n_words': 294, 'path': 'examples.ipynb', 'repo_name': 'the-code-critics/010-iterators', 'size': '3532'}