This is a generic recursive flatten which can be used to work with any combination of types which should or should not be flattened:
import collections
def generic_flatten(seq, flatten_types=(tuple,list,set),atom_types=(basestring,dict),fixtype=True):
newseq = []
for item in seq:
if (not isinstance(collections.Iterable)) or any(isinstance(i,t) for t in atom_types):
newseq.append(item)
elif any(isinstance(i,t) for t in flatten_types): # set flatten_types to (object,) or (collections.Iterable,) to disable check
newseq.extend(generic_flatten(item, flatten_types, atom_types,fixtype)
if fixtype and type(newseq) is not type(seq):
newseq = type(seq)(newseq)
return newseq
yield
and chain
could be used to create a generic iterator-based version.