2017-08-28 1 views
0

J'essaie de créer une fonction cython qui itère sur deux tableaux de chaînes chiffrés et crée une nouvelle liste de dicts à partir des données qui s'y trouvent. Je pensais que j'utiliserais C++ de Cython, je parcourais chacun de ces tableaux et construisais un vecteur de cartes au fur et à mesure. Je n'arrive pas à comprendre comment créer une carte vide à chaque itération.Création de mappes C++ dans une boucle en cython

Je voudrais faire quelque chose comme ceci:

def extract_data(words_seq, labels_seq, max_sentence_len): 
    cdef int i 
    cdef vector[map[string, vector[string]]] data 
    cdef vector[string] new_entry 

    data = [] 

    for i in range(len(words_seq)): 
     cdef map[string, vector[string]] new_row_map = {} 
     labels = labels_seq[i] 
     words = words_seq[i] 

     for j in range(max_sentence_len): 
      label = labels_seq[i][j] 
      word = words_seq[i][j] 

      if label == 'junk': 
       continue 
      elif new_row_map.count(label) == 0: 
       new_entry = [word] 
       new_row_map[label] = new_entry 
      else: 
       new_row_map[label].push_back(word) 
     data.push_back(new_row_map) 

    return data 

Mais je reçois l'erreur cdef statement not allowed here. Aussi, il n'aime pas que j'utilise un dictal littéral pour déclarer une carte vide.

Répondre

1

cdef doit être utilisé au niveau de la portée de la fonction
Je veux dire en dehors de la boucle

+0

Comment faire cela et créer une nouvelle carte à chaque itération? Si je déclare 'new_entry' en dehors de la boucle, je finis par ajouter la même carte avec de nouvelles entrées à chaque itération. – Luke

0

s'avère que je presque avait raison. Une copie de la carte est ajoutée au vecteur à chaque itération plutôt qu'un simple pointeur vers la carte. Cela semble donc fonctionner si vous déclarez la carte en dehors de la boucle, puis l'effacez à chaque itération.

def extract_data(words_seq, labels_seq, max_sentence_len): 
    cdef int i, j 
    cdef vector[map[string, vector[string]]] data 
    cdef vector[string] new_entry 
    cdef map[string, vector[string]] new_row_map 
    cdef str label, word 

    data = [] 

    for i in range(len(words_seq)): 

     for j in range(max_sentence_len): 
      label = labels_seq[i][j] 
      word = words_seq[i][j] 

      if label == 'junk': 
       continue 
      elif new_row_map.count(label) == 0: 
       new_entry = [word] 
       new_row_map[label] = new_entry 
      else: 
       new_row_map[label].push_back(word) 
     data.push_back(new_row_map) 
     new_row_map.clear() 

    return data