Comment puis-je obtenir le produit cartésien (toutes les combinaisons possibles de valeurs) à partir d'un groupe de listes?
Contribution:
somelists = [
[1, 2, 3],
['a', 'b'],
[4, 5]
]
Sortie désirée:
[(1, 'a', 4), (1, 'a', 5), (1, 'b', 4), (1, 'b', 5), (2, 'a', 4), (2, 'a', 5) ...]
set(cartesian product)
set(inputlist)
sur toutes vos listes de saisie. Pas sur le résultat.Réponses:
itertools.product
Disponible à partir de Python 2.6.
C'est la même chose que,
la source
product()
génère desnitems_in_a_list ** nlists
éléments dans le résultat (reduce(mul, map(len, somelists))
). Il n'y a aucune raison de croire que le fait de produire un seul élément n'est pasO(nlists)
(amorti), c'est-à-dire que la complexité temporelle est la même que pour lesfor
boucles imbriquées simples, par exemple, pour l'entrée dans la question :,nlists=3
nombre total d'éléments dans le résultat :,3*2*2
et chaque élément a desnlists
éléments (3
dans ce cas).*
avant les listes de diffusion? Qu'est ce que ça fait?la source
Pour Python 2.5 et versions antérieures:
Voici une version récursive de
product()
(juste une illustration):Exemple:
la source
args
sont des itérateurs.avec itertools.product :
la source
*
avant les listes de diffusion?J'utiliserais la compréhension de liste:
la source
Voici un générateur récursif, qui ne stocke aucune liste temporaire
Production:
la source
def f(): while True: yield 1
ci continuera d'augmenter la taille de sa pile au fur et à mesure?Dans Python 2.6 et supérieur, vous pouvez utiliser 'itertools.product`. Dans les anciennes versions de Python, vous pouvez utiliser le code équivalent suivant (presque - voir la documentation) de la documentation , au moins comme point de départ:
Le résultat des deux est un itérateur, donc si vous avez vraiment besoin d'une liste pour un traitement ultérieur, utilisez
list(result)
.la source
Bien qu'il existe déjà de nombreuses réponses, je voudrais partager certaines de mes réflexions:
Approche itérative
Approche récursive
Approche Lambda
la source
Approche récursive:
Approche itérative:
la source
Une modification mineure à la solution de générateur récursif ci-dessus de saveur variadique:
Et bien sûr, un wrapper qui le fait fonctionner exactement de la même manière que cette solution:
avec un compromis : il vérifie si la récursivité doit se briser sur chaque boucle externe, et un gain : pas de rendement lors d'un appel vide, par exemple
product(())
, ce qui, je suppose, serait sémantiquement plus correct (voir le doctorat).Concernant la compréhension de liste: la définition mathématique s'applique à un nombre arbitraire d'arguments, tandis que la compréhension de liste ne peut en traiter qu'un nombre connu.
la source
Juste pour ajouter un peu à ce qui a déjà été dit: si vous utilisez sympy, vous pouvez utiliser des symboles plutôt que des chaînes, ce qui les rend mathématiquement utiles.
À propos de sympy .
la source
Je crois que cela fonctionne:
la source
Approche de Stonehenge:
production:
la source