def iterate ( obj ) : global next , Iteration next = next Iteration = Iteration total = len ( obj ) if isinstance ( obj , Sized ) else None iterator = iter ( obj ) first = True last = False i = 0 try : value = next ( iterator ) except StopIteration : return while True : try : next_value = next ( iterator ) except StopIteration : last = True yield Iteration ( first , last , i , total , value ) if last : return value = next_value i += 1 first = False
fastest way to iterate python
Loop over an iterable and track progress including first and last state . On each iteration yield an Iteration named tuple with the first and last flags current element index total iterable length ( if possible to acquire ) and value in that order . for iteration in iterate ( something ) : iteration . value # Do something . You can unpack these safely : for first last index total value in iterate ( something ) : pass If you want to unpack the values you are iterating across you can by wrapping the nested unpacking in parenthesis : for first last index total ( foo bar baz ) in iterate ( something ) : pass Even if the length of the iterable can t be reliably determined this function will still capture the last state of the final loop iteration . ( Basically : this works with generators . ) This process is about 10x slower than simple enumeration on CPython 3 . 4 so only use it where you actually need to track state . Use enumerate () elsewhere .
def iterate(obj):
	"""Loop over an iterable and track progress, including first and last state.
	
	On each iteration yield an Iteration named tuple with the first and last flags, current element index, total
	iterable length (if possible to acquire), and value, in that order.
	
		for iteration in iterate(something):
			iteration.value  # Do something.
	
	You can unpack these safely:
	
		for first, last, index, total, value in iterate(something):
			pass
	
	If you want to unpack the values you are iterating across, you can by wrapping the nested unpacking in parenthesis:
	
		for first, last, index, total, (foo, bar, baz) in iterate(something):
			pass
	
	Even if the length of the iterable can't be reliably determined this function will still capture the "last" state
	of the final loop iteration.  (Basically: this works with generators.)
	
	This process is about 10x slower than simple enumeration on CPython 3.4, so only use it where you actually need to
	track state.  Use `enumerate()` elsewhere.
	"""
	
	global next, Iteration
	next = next
	Iteration = Iteration
	
	total = len(obj) if isinstance(obj, Sized) else None
	iterator = iter(obj)
	first = True
	last = False
	i = 0
	
	try:
		value = next(iterator)
	except StopIteration:
		return
	
	while True:
		try:
			next_value = next(iterator)
		except StopIteration:
			last = True
		
		yield Iteration(first, last, i, total, value)
		if last: return
		
		value = next_value
		i += 1
		first = False