Skip to content

Instantly share code, notes, and snippets.

@vitalizzare
Created January 10, 2021 19:50
Show Gist options
  • Select an option

  • Save vitalizzare/845ea983d7c4822174ff0a01c4aece40 to your computer and use it in GitHub Desktop.

Select an option

Save vitalizzare/845ea983d7c4822174ff0a01c4aece40 to your computer and use it in GitHub Desktop.
How can we tell if we are at the beginning, at the end, or within a generated sequence in python?
'''
From the @NumFOCUS telethon
title: Z for zip
author: @dontusethiscode
date: December 19, 2020
python version: >= 3.8
video: https://youtu.be/gzbmLeaM8gs?t=15648
edited by: @vitalizzare
date: January 10, 2021
'''
# Suppose different operations are to be performed on the first,
# last and inner generated elements. How can we tell if we are
# at the beginning, at the end, or within a sequence?
from itertools import islice, tee, repeat, chain, zip_longest
def first(g, n=1):
'''Mark first n items of a sequence g'''
marker = chain(repeat(True, n), repeat(False))
for mark, item in zip(marker, g):
yield mark, item
def nwise_longest(g, n=2, fv=object()):
'''Return a view on n sequentional elements of a sequence g'''
# Get a sequence of shifted generators g[i:] for i in range(n)
shifted = (islice(g, idx, None) for idx, g in enumerate(tee(g, n)))
for n_slice in zip_longest(*shifted, fillvalue=fv):
yield n_slice
def last(g, n=1, sentinel=object()):
'''Mark last n items of a sequence g'''
for x, *y in nwise_longest(g, n+1, sentinel):
yield y[-1] is sentinel, x
seq = 'abcd'
print(f'{seq = }')
for is_first, (is_last, item) in first(last(seq)):
if is_first:
print('START')
print('...', item)
if is_last:
print('STOP')
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment