J'ai les deux listes suivantes et j'essaie de trouver les mots communs entre eux. J'essaie d'extraire les mots de l2 (en ignorant le nombre) et de les stocker dans l3, mais je continue à recevoir l'erreur:

les indices de liste doivent être des entiers ou des tranches, pas des tuples

Je suis intéressé par un correctif ou s'il existe une meilleure approche de la solution.

l1=['the', 'and', 'to', 'of', 'a', 'in', 'is', 'that']
l2=[('the', 637), ('of', 252), ('a', 208), ('to', 207), ('in', 147), 
    ('and', 134), ('that', 134), ('was', 133)]


l3= list(map(lambda x: set(l2[x][x]), l2[0:6]))

print(set(l1 & l3))
1
Misu 8 avril 2020 à 11:02

4 réponses

Pour fixer votre propre approche:

l3 = set(map(lambda x: x[0], l2))  # first element from each pair in l2

print(set(l1) & l3)  # must intersect set and set, not list and set
1
schwobaseggl 8 avril 2020 à 08:17

Vous pouvez convertir votre liste l1 en set, puis vous pouvez utiliser une compréhension de liste:

l1= ['the', 'and', 'to', 'of', 'a', 'in', 'is', 'that']
l1 = set(l1)

l2=[('the', 637), ('of', 252), ('a', 208), ('to', 207), ('in', 147), ('and', 134), ('that', 134), ('was', 133)]

[t[0] for t in l2 if t[0] in l1]
0
kederrac 8 avril 2020 à 08:34

Utilisez set intersection:

s1 = set(l1)

i = s1.intersection( e[0] for e in l2 )

print(i) # set(['a', 'and', 'that', 'of', 'to', 'in', 'the'])

Définir l'intersection (la méthode) peut prendre n'importe quel itérable pour trouver l'intersection avec l'ensemble sur lequel vous l'appelez.


Votre erreur provient d'une mauvaise utilisation du lambda:

map(lambda x: set(l2[x][x]), l2[0:6]))

Chaque x est un élément de l2 (vous ne prenez que les six premiers éléments de l2. map prend chaque élément de l'itération d'entrée et applique la fonction que vous fournissez. Pour le premier élément de l2 ce serait:

set(l2[('the', 637)][('the', 637)]) 

Ce qui est clairement faux.

2
Patrick Artner 8 avril 2020 à 08:17

Vous pouvez utiliser une compréhension de liste et vérifier quel premier élément du tuple est contenu dans l1. Vous pouvez réduire la complexité de l'opération en construisant un set à partir de l1:

s1 = set(l1)

l3 = [s for s,*_ in l2 if s in s1]
# ['the', 'of', 'a', 'to', 'in', 'and', 'that']

Ou nous pourrions aussi utiliser zip et indexer sur le premier élément:

set(l1).intersection(list(zip(*l2))[0])

Notez que votre approche ne fonctionne pas car vous essayez d'indexer à l'aide de tuples. lambda x reçoit un tuple à chaque fois, car vous parcourez directement l2. Si vous avez des sous-listes de longueur 2, vous pouvez également envisager de travailler avec des dictionnaires, auxquels vous pouvez accéder à l'aide d'une clé donnée. Compte tenu de la structure de vos données, il semble que cela pourrait être une bonne alternative pour vous:

d = dict(l2)

[i for i in l1 if i in d]
# ['the', 'and', 'to', 'of', 'a', 'in', 'that']
2
yatu 8 avril 2020 à 08:33