import itertools import collections def is_non_string_sequence(seq): return isinstance(seq, collections.Sequence) and not isinstance(seq, basestring) def is_dict(d): return isinstance(d, collections.Mapping) or hasattr(d, 'iteritems') and not isinstance(d, basestring) def iterable_paths(o, level=0): if is_dict(o): seqs = [] for k, v in o.iteritems(): newseqs = iterable_paths(v, level=level+1) for newseq in newseqs: seqs.append([k]) seqs[-1].extend(newseq) elif is_non_string_sequence(o): seqs = [[]] for item in o: if not is_dict(item) and not is_non_string_sequence(item): seqs[-1].append(item) else: newseqs = iterable_paths(item, level=level+1) for newseq in newseqs: for s in seqs: s.extend(newseq) else: seqs = [[o]] return seqs def test_iterable_paths(): data = {'i think i will': {'not consider': {'refactoring': 'this'}, 'test': {'a': 'value', 'a':['list','ofthings', {'including':{'nesting':'vals'}}]}}, 'testing': {'Nones': None, 'emptystrings': ''}} expected = [['testing', 'emptystrings', ''], ['testing', 'Nones', None], ['i think i will', 'test', 'a', 'list', 'ofthings', 'including', 'nesting', 'vals'], ['i think i will', 'not consider', 'refactoring', 'this']] vals = iterable_paths(data) assert expected == vals test_iterable_paths()