Aplatir une liste peu profonde en Python

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

Existe-t-il un moyen simple d'aplatir une liste d'itérables avec une compréhension de liste, ou à défaut, que considérez-vous tous comme le meilleur moyen d'aplatir une liste peu profonde comme celle-ci, en équilibrant performances et lisibilité ?

J'ai essayé d'aplatir une telle liste avec une compréhension de liste imbriquée, comme ceci :

[image for image in menuitem for menuitem in list_of_menuitems] 

Mais j'ai des problèmes avec la variété NameError, car le nom "menuitem" n'est pas défini. Après avoir cherché sur Google et regardé autour de Stack Overflow, j'ai obtenu les résultats souhaités avec une instruction reduce :

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

Mais cette méthode est assez illisible car j'ai besoin de cet appel list(x) car x est un Django QuerySet objet.

Conclusion :

Merci à tous ceux qui ont contribué à cette question. Voici un résumé de ce que j'ai appris. J"en fais également un wiki communautaire au cas où d"autres voudraient ajouter ou corriger ces observations.

Mon instruction de réduction originale est redondante et est mieux écrite de cette façon :

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

Ceci est la syntaxe correcte pour une compréhension de liste imbriquée (résumé brillant dF !):

>>> [image pour mi dans list_of_menuitems pour l'image in mi] 

Mais aucune de ces méthodes n'est aussi efficace que l'utilisation de itertools.chain :

>>> ; à partir de la chaîne d'importation itertools >>> list(chain(*list_of_menuitems)) 

Et comme le note @cdleary, il est probablement préférable d'éviter la magie de l'opérateur * en utilisant chain.from_iterable comme ceci :

>>> chaîne = itertools.chain.from_iterable([[1,2],[3],[5,89],[],[6]]) >>> print(list(chain)) >>> [1, 2, 3, 5, 89, 6]