def flatten(x): r""" >>> flatten("hello") 'hello' >>> flatten({"a":[["hi"]]}) {'a': [['hi']]} >>> flatten(None) is None True >>> flatten(3) 3 >>> flatten([0, [1, ["two"]]]) [0, 1, 'two'] >>> flatten( (0, (1, ("two",))) ) (0, 1, 'two') >>> flatten([0, [1, 2], 3, ([4, 5], 6)]) [0, 1, 2, 3, 4, 5, 6] >>> flatten( (0, 1, (i + 1 for i in xrange(1, 3)) ) ) (0, 1, 2, 3) >>> flatten([[[[[0]]]]]) [0] >>> flatten([0, [[{"a":[["hi"]]}]]]) [0, {'a': [['hi']]}] """ if isinstance(x, basestring): return x if hasattr(x, "__iter__"): if hasattr(x, "items"): return x else: return x is_tuple = isinstance(x, tuple) # leave exception here unhandled # if conversion to list fails x = list(x) x.reverse() r = [] while x: y = x.pop(-1) if isinstance(y, basestring): r.append(y) continue if hasattr(y, "__iter__"): if hasattr(y, "items"): r.append(y) continue else: r.append(y) continue # leave exception here unhandled # if conversion to list fails y = list(y) y.reverse() x.extend(y) if is_tuple: return tuple(r) else: return r