119 votes

compréhensions de liste de python; compresser une liste de listes?

les gars. J'essaie de trouver la solution la plus élégante à un problème et je me demandais si python a rien construit pour ce que je suis en train de faire.

Ce que je fais, c'est ça. J'ai une liste, A, et j'ai une fonction f qui prend un élément et renvoie une liste. Je peux utiliser une liste de compréhension de tout convertir en A comme;

[f(a) for a in A]

Mais ce retour une liste de listes;

[a1,a2,a3] => [[b11,b12],[b21,b22],[b31,b32]]

Ce que je veux vraiment, c'est obtenir la liste aplatie;

[b11,b12,b21,b22,b31,b32]

Maintenant, d'autres langues; il est appelé traditionnellement" flatmap dans les langages de programmation fonctionnelle, et .Net appelle SelectMany. Python ont quelque chose de semblable? Est-il un moyen sympa de carte d'une fonction sur une liste et aplatir le résultat?

Le réel problème, je vais essayer de résoudre est-ce, en commençant par une liste de répertoires, de trouver tous les sous-répertoires. de la sorte;

import os
dirs = ["c:\\usr", "c:\\temp"]
subs = [os.listdir(d) for d in dirs]
print subs

currentliy me donne une liste de listes, mais je veux vraiment une liste.

165voto

Ants Aasma Points 22921

Vous pouvez avoir des itérations nichées dans une seule liste de compréhension:

96voto

Julian Points 334
<pre><code></code><p>Je devine que la solution itertools est plus efficace que cela, mais cela se sent très pythonique et évite d'avoir à importer une bibliothèque juste pour le bien d'une opération de liste unique.</p></pre>

73voto

Roberto Liffredo Points 15265

Vous pouvez trouver une bonne réponse dans les recettes d'itertools :

(Remarque : nécessite Python 2.6' )

24voto

Anon Points 3418

Vous pourriez simplement faire le simple:

16voto

Martin Geisler Points 44779

Vous pouvez concaténer des listes à l'aide de la normale opérateur d'addition:

>>> [1, 2] + [3, 4]
[1, 2, 3, 4]

La fonction intégrée sum permettra d'ajouter les numéros de séquence et peut éventuellement commencer à partir d'une valeur spécifique:

>>> sum(xrange(10), 100)
145

Combiner les ci-dessus pour l'aplatir une liste de listes:

>>> sum([[1, 2], [3, 4]], [])
[1, 2, 3, 4]

Vous pouvez maintenant définir votre flatmap:

>>> def flatmap(f, seq):
...   return sum([f(s) for s in seq], [])
... 
>>> flatmap(range, [1,2,3])
[0, 0, 1, 0, 1, 2]

Edit: je viens de voir la critique dans les commentaires pour une autre réponse et je suppose que c'est correct que Python inutilement construire et les ordures de recueillir beaucoup de listes plus petites avec cette solution. Donc, la meilleure chose que l'on puisse dire, c'est que c'est très simple et concise si vous êtes habitué à la programmation fonctionnelle :-)

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X