J'ai une liste de listes. J'ai besoin d'obtenir toutes les combinaisons de ces listes de 2 de N à N de N . Je le recherche avec itertools.combinations. Après cela, j'ai obtenu une liste de listes et je dois les combiner sans doublons.

Par exemple, j'ai un tableau:

a = np.array([[1,4,7],[8,2,5],[8,1,4,6],[8,1,3,5],
              [2,3,4,7],[2,5,6,7],[2,3,4,6,8],[1,3,5,6,7]])

Je recherche les 3 combinaisons d'éléments:

a2 = list(itertools.combinations(a, 3))

a2[:5]
[([1, 4, 7], [8, 2, 5], [8, 1, 4, 6]),
 ([1, 4, 7], [8, 2, 5], [8, 1, 3, 5]),
 ([1, 4, 7], [8, 2, 5], [2, 3, 4, 7]),
 ([1, 4, 7], [8, 2, 5], [2, 5, 6, 7]),
 ([1, 4, 7], [8, 2, 5], [2, 3, 4, 6, 8])]

La longueur de ce tableau: 56. J'ai besoin de combiner toutes les listes de ce tableau sans doublons. Par exemple pour l'entrée a2 [0]:

([1, 4, 7], [8, 2, 5], [8, 1, 4, 6])

Production:

[1, 2, 4, 5, 6, 7, 8]

Et donc tous les 56 éléments. J'ai essayé de le faire avec set :

arr = list(itertools.combinations(a,3))
for i in arr:
    arrnew[i].append(list(set().union(arr[i][:3])))

Mais j'avais une erreur:

TypeError                                 Traceback (most recent call last)
<ipython-input-75-4049ddb4c0be> in <module>()
      3 arrnew = []
      4 for i in arr:
----> 5     for j in arr[i]:
      6         arrnew[i].append(list(set().union(arr[:n])))

TypeError: list indices must be integers or slices, not tuple

J'ai besoin d'une fonction pour N combinaisons, qui renvoie un nouveau tableau combiné. Mais je ne sais pas comment faire cela à cause de cette erreur.

Existe-t-il un moyen de résoudre cette erreur ou une autre façon de résoudre cette tâche?

-1
FeoJun 16 avril 2018 à 14:41

4 réponses

Meilleure réponse

Une petite fonction qui le résout:

def unique_comb(a):
    return list(set(itertools.chain(*a)))

Par exemple:

unique_comb(([1, 4, 7], [8, 2, 5], [8, 1, 4, 6]))

Si vous voulez passer une liste comme argument à la fonction, plutôt qu'une liste à l'intérieur d'un tuple, supprimez simplement le * (qui décompresse la liste).

Si vous souhaitez l'appliquer à l'ensemble du tableau dans une seule instruction sans définir de fonction:

a3 = [list(set(itertools.chain(*row))) for row in a2]
1
ksbg 16 avril 2018 à 11:58

Le problème avec:

arr = list(itertools.combinations(a,3))
for i in arr:
    arrnew[i].append(list(set().union(arr[i][:3])))

Est-ce que i n'est pas l'index de l'élément mais l'élément de la liste lui-même.

Ce dont vous avez besoin c'est:

import itertools
import numpy as np
a = np.array([[1,4,7],[8,2,5],[8,1,4,6],[8,1,3,5],
              [2,3,4,7],[2,5,6,7],[2,3,4,6,8],[1,3,5,6,7]])
arrnew = []

for item in itertools.combinations(a,3):
    arrnew.append(list(set().union(*item)))

Le résultat arrnew contient 56 éléments. Certains sont égaux mais aucun ne contient de doublons.

Je vous suggère d'utiliser sorted plutôt que list pour vous assurer que les éléments de chaque liste combinée sont en ordre croissant.

0
Dan D. 16 avril 2018 à 12:06

Mise à plat d'un tuple de listes:

from itertools import chain
new_tuple = [ list(set(chain.from_iterable(each_tuple))) for each_tuple in main_tuple_coll ]

Je pense que cela pourrait résoudre votre problème.

0
Kenstars 16 avril 2018 à 11:50

Aplatir les combinaisons de listes

comb = []
for line in a2[:3]:
    l = list(set([x for y in line for x in y]))
    comb.append(l)
comb

[en dehors]

[[1, 2, 4, 5, 6, 7, 8], [1, 2, 3, 4, 5, 7, 8], [1, 2, 3, 4, 5, 7, 8]]
0
michaelg 16 avril 2018 à 12:00