Is there a way of avoiding so many list(chain(*list_of_list))?

本秂侑毒 提交于 2019-12-24 03:52:31

问题


If I have a list of list of list of tuples of two strings. I want to flatten it out to a non-nested list of tuples, I could do this:

>>> from itertools import chain
>>> lst_of_lst_of_lst_of_tuples = [ [[('ab', 'cd'), ('ef', 'gh')], [('ij', 'kl'), ('mn', 'op')]], [[('qr', 'st'), ('uv', 'w')], [('x', 'y'), ('z', 'foobar')]] ]
>>> lllt = lst_of_lst_of_lst_of_tuples
>>> list(chain(*list(chain(*lllt))))
[('ab', 'cd'), ('ef', 'gh'), ('ij', 'kl'), ('mn', 'op'), ('qr', 'st'), ('uv', 'w'), ('x', 'y'), ('z', 'foobar')]

But is there another way of unpacking to the non-nested list of tuples withou the nested list(chain(*lst_of_lst))?


回答1:


You could keep unpacking until you hit tuples:

def unpack_until(data, type_):
    for entry in data:
        if isinstance(entry, type_):
            yield entry
        else:
            yield from unpack_until(entry, type_)

Then:

>>> list(unpack_until(lllt, tuple))
[('ab', 'cd'),
 ('ef', 'gh'),
 ('ij', 'kl'),
 ('mn', 'op'),
 ('qr', 'st'),
 ('uv', 'w'),
 ('x', 'y'),
 ('z', 'foobar')]



回答2:


You don't need to call list before unpacking an iterator:

list(chain(*chain(*lllt)))

It may be better to use chain.from_iterable rather than unpacking, to work with iterators instead of materializing them into tuples with *:

flatten = chain.from_iterable
list(flatten(flatten(lllt)))


来源:https://stackoverflow.com/questions/30878953/is-there-a-way-of-avoiding-so-many-listchainlist-of-list

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!