iteranything
Monday, May 7th, 2007Here’s a Python function to iterate over pretty much anything. In the extremely unlikely event that anyone uses this code, note that if you pass keyword arguments the order of the resulting iteration is not defined (as with iterating through any Python dictionary).
import types
def iteranything(*args, **kwargs):
for arg in chain(args, kwargs.itervalues()):
t = type(arg)
if t == types.StringType:
yield arg
elif t == types.FunctionType:
for i in arg():
yield i
else:
try:
i = iter(arg)
except TypeError:
yield arg
else:
while True:
try:
yield i.next()
except StopIteration:
break
if __name__ == ‘__main__’:
def gen1():
yield 1
yield 2
def gen2():
yield 3
yield 4
assert list(iteranything()) == []
assert list(iteranything([])) == []
assert list(iteranything([[]])) == [[]]
assert list(iteranything([], [])) == []
assert list(iteranything(3)) == [3]
assert list(iteranything(3, 4)) == [3, 4]
assert list(iteranything(3, 4, dog=‘fido’)) == [3, 4, ‘fido’]
assert list(iteranything(3, 4, func=gen1)) == [3, 4, 1, 2]
assert list(iteranything(3, 4, func=gen1())) == [3, 4, 1, 2]
assert list(iteranything(3, 4, func=iteranything)) == [3, 4]
assert list(iteranything(3, 4, func=iteranything())) == [3, 4]
assert list(iteranything(3, 4, func=iteranything(‘a’, ‘b’, c=‘z’))) ==
[3, 4, ‘a’, ‘b’, ‘z’]
assert list(iteranything(3, 4, func=iteranything(‘a’,
iteranything(5, 6), c=‘z’))) == [3, 4, ‘a’, 5, 6, ‘z’]
assert list(iteranything(None, ‘xxx’, True)) == [None, ‘xxx’, True]
assert list(iteranything(3, 4, [5, 6])) == [3, 4, 5, 6]
assert list(iteranything(3, 4, gen1, gen2)) == [3, 4, 1, 2, 3, 4]
assert list(iteranything(3, 4, gen1(), gen2())) == [3, 4, 1, 2, 3, 4]
assert list(iteranything(1, 2, iteranything(3, 4), None)) ==
[1, 2, 3, 4, None]
assert list(iteranything(1, 2, iteranything(3, iteranything(1, 2,
iteranything(3, 4), None)))) == [1, 2, 3, 1, 2, 3, 4, None]