Создать уникальные идентификаторы для списка списков со словами

Другой пример:

class func getExchangeRate(#baseCurrency: String, foreignCurrency:String, completion: ((result:Double?) -> Void)!){
    let baseURL = kAPIEndPoint
    let query = String(baseCurrency)+"_"+String(foreignCurrency)

    var finalExchangeRate = 0.0
    if let url = NSURL(string: baseURL + query) {
        NSURLSession.sharedSession().dataTaskWithURL(url) { data, response, error in

            if ((data) != nil) {
                let jsonDictionary:NSDictionary = NSJSONSerialization.JSONObjectWithData(data!, options: nil, error: nil) as NSDictionary

                if let results = jsonDictionary["results"] as? NSDictionary{
                    if let queryResults = results[query] as? NSDictionary{
                        if let exchangeRate = queryResults["val"] as? Double{
                            let priority = DISPATCH_QUEUE_PRIORITY_DEFAULT
                            dispatch_async(dispatch_get_global_queue(priority, 0)) {
                                dispatch_async(dispatch_get_main_queue()) {
                                    completion(result: exchangeRate)
                                }
                            }

                        }
                    }
                }
            }
            else {
                completion(result: nil)
            }

        }.resume()
    }
}    

Вызов:

 Currency.getExchangeRate(baseCurrency: "USD", foreignCurrency: "EUR") { (result) -> Void in
                if let exchangeValue = result {
                    print(exchangeValue)
                }
            }
1
задан Martijn Pieters 16 January 2019 в 16:41
поделиться

2 ответа

Есть две проблемы:

  1. Вы сделали опечатку, повторив поиск word1 в word_to_id.
  2. При создании словаря word_to_id необходимо учитывать только уникальные значения.

Например, в Python 3.7+ вы можете использовать словари с упорядочением вставки:

for i, word in enumerate(dict.fromkeys(vocabulary)):
    word_to_id[word] = i

for word1, word2 in labels:
    ids.append([word_to_id[word1], word_to_id[word2]])

Альтернативой для версий до 3.7 является использование collections.OrderedDict [118 ] или itertools unique_everseen рецепт .

Если нет требования к упорядочению, вы можете просто использовать set(vocabulary).

0
ответ дан jpp 16 January 2019 в 16:41
поделиться

У вас есть две ошибки. Во-первых, у вас есть простая опечатка, здесь:

for word1,word2 in labels:
    ids.append([word_to_id [word1], word_to_id [word1]])

Вы добавляете идентификатор для word1 дважды , там. Исправьте второй word1, чтобы найти word2 вместо этого.

Далее, вы не проверяете, видели ли вы слово раньше, поэтому для 'Kleiber' вы сначала даете ему идентификатор 4, а затем переписываете эту запись на 6 на следующей итерации. Вам нужно дать уникальные слова, а не все слова:

counter = 0
for word in vocabulary:
    if word not in word_to_id:
        word_to_id[word] = counter
        counter += 1

, иначе вы просто не можете добавить слово в vocabulary, если у вас уже есть это слово в списке. Кстати, вам не нужен отдельный список vocabulary. Отдельный цикл ничего не покупает, поэтому работает также следующее:

word_to_id = {}
counter = 0
for words in labels:
    for word in words:
        word_to_id [word] = counter
        counter += 1

Вы можете немного упростить свой код, используя defaultdict объект и itertools.count() для предоставления значений по умолчанию:

from collections import defaultdict
from itertools import count

def words_to_ids(labels):
    word_ids = defaultdict(count().__next__)
    return [[word_ids[w1], word_ids[w2]] for w1, w2 in labels]

Объект count() дает вам следующее целочисленное значение в серии каждый раз, когда вызывается __next__, и defaultdict() будет вызывать это каждое время, когда вы пытаетесь получить доступ к ключу, который еще не существует в словаре. Вместе они обеспечивают уникальный идентификатор для каждого уникального слова.

0
ответ дан Martijn Pieters 16 January 2019 в 16:41
поделиться
Другие вопросы по тегам:

Похожие вопросы: