Spłaszczanie płytkiej listy w Pythonie

| | | | | | | | | | | | | |

Czy istnieje prosty sposób na spłaszczenie listy iterowalnych za pomocą rozumienia listy, czy w przypadku jej braku, co wszyscy uważacie za najlepszy sposób na spłaszczenie tak płytkiej listy, równoważąc wydajność i czytelność?

Próbowałem spłaszczyć taką listę za pomocą zagnieżdżonego rozumienia listy, tak jak to:

[obraz dla obrazu w pozycji menu dla pozycji menu w liście_of_menuitems] 

Ale mam kłopoty z odmianą NameError, ponieważ nazwa "menuitem" nie jest zdefiniowana. Po googlowaniu i rozglądaniu się po Stack Overflow uzyskałem pożądane wyniki za pomocą instrukcji reduce:

reduce(list.__add__, map(lambda x: list(x) ), list_of_menuitems)) 

Ale ta metoda jest dość nieczytelna, ponieważ potrzebuję wywołania list(x), ponieważ x jest Django QuerySet obiekt.

Wniosek:

Dziękujemy wszystkim, którzy przyczynili się do odpowiedzi na to pytanie. Oto podsumowanie tego, czego się nauczyłem. Robię to również wiki społeczności na wypadek, gdyby inni chcieli dodać lub poprawić te obserwacje.

Moja oryginalna instrukcja Reduce jest zbędna i lepiej jest napisać w ten sposób:

>>>reduce(list.__add__, (list(mi) for mi in list_of_menuitems)) 

To jest poprawna składnia dla zagnieżdżonego rozumienia listy (świetne podsumowanie dF!):

>>> [obraz dla mi w list_of_menuitems dla obrazu in mi] 

Ale żadna z tych metod nie jest tak wydajna jak użycie itertools.chain:

>>> ; z itertools import chain >>> list(chain(*list_of_menuitems)) 

I jak zauważa @cdleary, prawdopodobnie lepszym stylem jest unikanie * magii operatorów za pomocą chain.from_iterable na przykład:

>>> łańcuch = itertools.chain.from_iterable([[1,2],[3],[5,89],[],[6]]) >>>> print(list(łańcuch)) >>> [1, 2, 3, 5, 89, 6]