1
votes

Itération de liste imbriquée

J'essayais un prétraitement sur une liste imbriquée avant d'essayer un petit mot2vec et j'ai rencontré un problème comme suit:

for _ in range(0, len(corpus)):
     for x in corpus[_]:
         if x == 'is' or x == 'a':
             corpus[_].remove(x)

[['il', 'est', 'a', 'courageux', 'roi'], ['elle', 'est', 'a', 'gentille', 'reine'], [' il ',' est ',' un ',' jeune ',' garçon '], [' elle ',' est ',' a ',' douce ',' fille ']]

Donc, la sortie ci-dessus était donnée sous forme de liste imbriquée et j'avais l'intention de supprimer les mots vides, par exemple 'est', 'a'.

corpus = ['he is a brave king', 'she is a kind queen', 'he is a young boy', 'she is a gentle girl']

corpus = [_.split(' ') for _ in corpus]

[['il', 'a', 'courageux', 'roi'], ['elle', 'une', 'gentille', 'reine'], ['il', 'a', ' jeune ',' garçon '], [' elle ',' a ',' douce ',' fille ']]

Le résultat semble indiquer que la boucle est passée à la sous-liste suivante après avoir supprimé «is» dans chaque sous-liste au lieu de l'itérer entièrement.

Quel est le raisonnement derrière cela? Indice? Si tel est le cas, comment résoudre le problème en supposant que je souhaite conserver la structure imbriquée.


0 commentaires

3 Réponses :


2
votes

Tout ce que vous codez est correct, sauf une modification mineure: utilisez [:] pour parcourir le contenu en utilisant une copie de la liste et éviter de faire des changements via la référence à la liste d'origine. Plus précisément, vous créez une copie d'une liste sous la forme lst_copy = lst [:] . C'est une façon de copier parmi plusieurs autres (voir ici pour plus d'informations façons). Lorsque vous parcourez la liste d'origine et que vous modifiez la liste en supprimant des éléments, le compteur crée le problème que vous observez.

[['he', 'brave', 'king'],
 ['she', 'kind', 'queen'],
 ['he', 'young', 'boy'],
 ['she', 'gentle', 'girl']]

OUTPUT

for _ in range(0, len(corpus)):
     for x in corpus[_][:]: # <--- create a copy of the list using [:]
         if x == 'is' or x == 'a':
             corpus[_].remove(x)


0 commentaires

0
votes

nested = [entrée ()]

nested = [i.split () for i in nested]


1 commentaires

Bien que cet extrait de code puisse résoudre la question, y compris une explication contribue vraiment à améliorer la qualité de votre message. N'oubliez pas que vous répondez à la question aux lecteurs à l'avenir, et que ces personnes pourraient ne pas connaître les raisons de votre suggestion de code. Essayez également de ne pas surcharger votre code avec des commentaires explicatifs, cela réduit la lisibilité du code et des explications!



1
votes

Vous pouvez peut-être définir une méthode personnalisée pour rejeter les éléments correspondant à une certaine condition. Similaire à itertools (par exemple: itertools.drop while ).

stopwords = ['is', 'and', 'a']
[ list(reject_if(lambda x: x in stopwords, ary)) for ary in corpus ]
#=> [['he', 'brave', 'king'], ['she', 'kind', 'queen'], ['he', 'young', 'boy'], ['she', 'gentle', 'girl']]

Une fois la méthode en place, vous pouvez utiliser cette méthode:

def reject_if(predicate, iterable):
  for element in iterable:
    if not predicate(element):
      yield element


0 commentaires