2016-09-04 5 views
0

Я пытаюсь сделать уникальный идентификатор из списка слов. Я хочу, чтобы эти цифры были глобально уникальными. Например, если появляется другой список, я хочу, чтобы уникальный идентификатор был таким же, например. для «плотности» идентификатор может быть 151111911, и это будет то же самое, если «плотность» встречается в другом списке.Не удается получить уникальные идентификаторы для строки python2.7

Как вы можете видеть, мой текущий метод не работает, используя id и intern - идентификатор для rrb точно так же, как и lrb.

featureList = [u'guinea', u'bissau', u'compared', u'countriesthe', u'population', u'density', u'guinea', u'bissau', u'similar', u'iran', u'afghanistan', u'cameroon', u'panama', u'montenegro', u'guinea', u'belarus', u'palau', u'location_slot', u'south', u'africa', u'respective', u'population', u'density', u'lrb', u'capita', u'per', u'square', u'kilometer', u'rrb', u'global', u'rank', u'number_slot', u'years', u'growthguinea', u'bissau', u'population', u'density', u'positive', u'growth', u'lrb', u'rrb', u'last', u'years', u'lrb', u'rrb', u'LOCATION_SLOT~-appos+LOCATION~-prep_of', u'LOCATION~-prep_of+that~-prep_to', u'that~-prep_to+similar~prep_with', u'similar~prep_with+density~prep_of', u'density~prep_of+NUMBER~appos', u'NUMBER~appos+NUMBER~amod', u'NUMBER~amod+NUMBER_SLOT'] 

featureVector = mydefaultdict(mydouble) 

for featureID,featureVal in enumerate(featureList): 
     print "featureID is",featureID 
     print "featureVal is ",featureVal 
     print "Encoded feature value is", id(intern(str(featureVal.encode("utf-8")))) 
     featureVector[featureID] = featureVal 


featureID is 0 
featureVal is guinea 
Encoded feature value is 4569583120.0 
featureID is 1 
featureVal is bissau 
Encoded feature value is 4569581632.0 
featureID is 2 
featureVal is compared 
Encoded feature value is 4569583120.0 
featureID is 3 
featureVal is countriesthe 
Encoded feature value is 4567944360.0 
featureID is 4 
featureVal is population 
Encoded feature value is 4347153072.0 
featureID is 5 
featureVal is density 
Encoded feature value is 4455561472.0 
featureID is 6 
featureVal is guinea 
Encoded feature value is 4569581632.0 
featureID is 7 
featureVal is bissau 
Encoded feature value is 4569583120.0 
featureID is 8 
featureVal is similar 
Encoded feature value is 4496118144.0 
featureID is 9 
featureVal is iran 
Encoded feature value is 4569583120.0 
featureID is 10 
featureVal is afghanistan 
Encoded feature value is 4569581632.0 
featureID is 11 
featureVal is cameroon 
Encoded feature value is 4569583120.0 
featureID is 12 
featureVal is panama 
Encoded feature value is 4569581632.0 
featureID is 13 
featureVal is montenegro 
Encoded feature value is 4569583120.0 
featureID is 14 
featureVal is guinea 
Encoded feature value is 4569581632.0 
featureID is 15 
featureVal is belarus 
Encoded feature value is 4569583120.0 
featureID is 16 
featureVal is palau 
Encoded feature value is 4569581632.0 
featureID is 17 
featureVal is location_slot 
Encoded feature value is 4567944360.0 
featureID is 18 
featureVal is south 
Encoded feature value is 4569583120.0 
featureID is 19 
featureVal is africa 
Encoded feature value is 4569581632.0 
featureID is 20 
featureVal is respective 
Encoded feature value is 4569583120.0 
featureID is 21 
featureVal is population 
Encoded feature value is 4347153072.0 
featureID is 22 
featureVal is density 
Encoded feature value is 4455561472.0 
featureID is 23 
featureVal is lrb 
Encoded feature value is 4537993216.0 
featureID is 24 
featureVal is capita 
Encoded feature value is 4569581632.0 
featureID is 25 
featureVal is per 
Encoded feature value is 4455914152.0 
featureID is 26 
featureVal is square 
Encoded feature value is 4347127296.0 
featureID is 27 
featureVal is kilometer 
Encoded feature value is 4569581632.0 
featureID is 28 
featureVal is rrb 
Encoded feature value is 4537993216.0 
featureID is 29 
featureVal is global 
Encoded feature value is 4346597072.0 
featureID is 30 
featureVal is rank 
Encoded feature value is 4346629984.0 
featureID is 31 
featureVal is number_slot 
Encoded feature value is 4569583120.0 
featureID is 32 
featureVal is years 
Encoded feature value is 4569581632.0 
featureID is 33 
featureVal is growthguinea 
Encoded feature value is 4567944360.0 
featureID is 34 
featureVal is bissau 
Encoded feature value is 4569583120.0 
featureID is 35 
featureVal is population 
Encoded feature value is 4347153072.0 
featureID is 36 
featureVal is density 
Encoded feature value is 4455561472.0 
featureID is 37 
featureVal is positive 
Encoded feature value is 4514096160.0 
featureID is 38 
featureVal is growth 
Encoded feature value is 4569583120.0 
featureID is 39 
featureVal is lrb 
Encoded feature value is 4537993216.0 
featureID is 40 
featureVal is rrb 
Encoded feature value is 4537993216.0 
featureID is 41 
featureVal is last 
Encoded feature value is 4346568112.0 
featureID is 42 
featureVal is years 
Encoded feature value is 4569583120.0 
featureID is 43 
featureVal is lrb 
Encoded feature value is 4537993216.0 
featureID is 44 
featureVal is rrb 
Encoded feature value is 4537993216.0 
featureID is 45 
featureVal is LOCATION_SLOT~-appos+LOCATION~-prep_of 
Encoded feature value is 4538026784.0 
featureID is 46 
featureVal is LOCATION~-prep_of+that~-prep_to 
Encoded feature value is 6043251168.0 
featureID is 47 
featureVal is that~-prep_to+similar~prep_with 
Encoded feature value is 6043251168.0 
featureID is 48 
featureVal is similar~prep_with+density~prep_of 
Encoded feature value is 6043251168.0 
featureID is 49 
featureVal is density~prep_of+NUMBER~appos 
Encoded feature value is 6043251168.0 
featureID is 50 
featureVal is NUMBER~appos+NUMBER~amod 
Encoded feature value is 6043247024.0 
featureID is 51 
featureVal is NUMBER~amod+NUMBER_SLOT 
Encoded feature value is 6043247024.0 

Что я делаю неправильно? Причина, по которой мне нужно преобразовать их в поплавки или числа, заключается в том, что приведенное выше предложение будет входить в классификатор, который должен использовать числовые/векторизованные функции.

+0

Я не понимаю, как это должно работать, но вы можете искать модуль 'uuid'. – karlosss

+0

Кажется, что конвертирует строки Unicode в уникальные идентификаторы? Только 16-значный гекс? https://docs.python.org/2/library/uuid.html#module-uuid. –

+0

Идентификатор 'id' Python ** не предназначен для использования таким образом. В CPython возвращаемое значение - это просто адрес памяти базовых объектов, и python может повторно использовать эти объекты, что означает, что один и тот же идентификатор может быть связан с разными объектами в течение всего жизненного цикла программы. Я просто оставил «itertools».count() 'object для создания идентификаторов, списка объектов, которые мы отслеживаем, и' dict', который сопоставляет объекты с их идентификаторами (таким образом, у вас есть как отображения из объектов в идентификаторы, так и из идентификаторов в объекты путем простой индексации этот список). – Bakuriu

ответ

2

Из docs

интернированы струн не бессмертны (как они привыкли быть в Python 2.2 и выше); вы должны сохранить ссылку на возвращаемое значение intern() вокруг, чтобы извлечь из этого выгоду.

В то время, когда следующая строка интернирована, предыдущие строки могут быть удалены, а новые могут иногда иметь один и тот же идентификатор. Поэтому храните ссылки в контейнере. Я буду использовать Dict:

featureList = [u'guinea', u'bissau', u'compared', u'countriesthe', u'population', u'density', u'guinea', u'bissau', u'similar', u'iran', u'afghanistan', u'cameroon', u'panama', u'montenegro', u'guinea', u'belarus', u'palau', u'location_slot', u'south', u'africa', u'respective', u'population', u'density', u'lrb', u'capita', u'per', u'square', u'kilometer', u'rrb', u'global', u'rank', u'number_slot', u'years', u'growthguinea', u'bissau', u'population', u'density', u'positive', u'growth', u'lrb', u'rrb', u'last', u'years', u'lrb', u'rrb', u'LOCATION_SLOT~-appos+LOCATION~-prep_of', u'LOCATION~-prep_of+that~-prep_to', u'that~-prep_to+similar~prep_with', u'similar~prep_with+density~prep_of', u'density~prep_of+NUMBER~appos', u'NUMBER~appos+NUMBER~amod', u'NUMBER~amod+NUMBER_SLOT'] 

# dict of id:featureVal pairs 
seen = {} 

for featureID,featureVal in enumerate(featureList): 
    print "featureID is",featureID 
    print "featureVal is ",featureVal 
    interned = intern(str(featureVal.encode("utf-8"))) 
    interned_id = id(interned) 

    # ensure that no other string with the same id has been seen 
    assert interned_id not in seen or seen[interned_id] == featureVal 

    # change this to seen[interned_id] = None and you'll (probably) get AssertionError 
    # from the line above 
    seen[interned_id] = interned 

    print "Encoded feature value is", interned_id 
+0

Где 'val' defined? –

+0

@DhruvGhulati отредактировал – robyschek

+0

Да, это работает! Может быть, для улучшения ответа объясните, что делает шаг' assert'? –

-1

Вы можете напрямую использовать функцию hash() в Python. Хэш функция возвращает уникальный хэш, который может быть использован в качестве идентификатора для любой заданной строки, как это ваш случай, но она может отличаться на разных платформах (32 бит/64 бит, OS, питон версия)

hash("answer") 
-8597262460139880008 

Если вы хочу, чтобы хэши были одинаковыми, тогда вы можете использовать модуль Pythons hashlibs, но это не даст вам номеров. Он вернет хэш-строку.

import hashlib 
test = hashlib.sha224() 
test.update("HI How are you") 
test.hexdigest() 
'3284ec5f391e0c6b4f974d3bc317a77bb50875081d2bcb2436fc2001' 

Вы можете выбрать из различных алгоритмов

hashlib.algorithms 
('md5', 'sha1', 'sha224', 'sha256', 'sha384', 'sha512') 
+0

Могу ли я хранить все отдельные слова, используя это? Или он изменяет встроенный? PLS вы могли бы показать, как я могу обратиться к моему списку? –

+0

Вам нужно обработать каждое слово, используя любой из двух подходов. Замените часть кода, которая генерирует featureVal с помощью кода выше, и он выполнит задание. вы можете хранить его так, как хотите. – Sharad

+1

Нет, функция hash не возвращает уникальные идентификаторы. Они возвращают хеши. Возможно иметь две разные строки с одинаковым значением хэш-функции. Даже с ша224. – Messa

1

Вы можете использовать сами слова, хэш слова, или даже может преобразовать строку в число.

+0

Как преобразовать строку в число? По персонажам? Не могли бы вы опубликовать код, который я могу проверить на PLS? –

+0

Итак, вы хотите взять двоичное представление каждого символа в виде строки (с 'format (ord (c), 'b'). Zfill (8)' и объединить их все вместе. это с '.join (format (ord (c),' b '). zfill (8) для c в строке). Затем вы хотите преобразовать в целое как таковое: 'int (' 0b '+' '. join (формат (ord (c), 'b'). zfill (8) для c в строке), 2) '. Вы должны добавить битную строку с 0b, иначе она будет интерпретировать ее как целое напрямую. –

1

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

from collections import defaultdict 
from itertools import count 

# Start from 1.0 and increment by one - can change to start from any value or even add a step 
# eg: `count(716345.0, 9)` will start at at 716345.0 and increment by 9 for new keys 
unique_id = defaultdict(lambda c=count(1.0): next(c)) 
featureList = [u'guinea', u'bissau', u'compared', u'countriesthe', u'population', u'density', u'guinea', u'bissau', u'similar', u'iran', u'afghanistan', u'cameroon', u'panama', u'montenegro', u'guinea', u'belarus', u'palau', u'location_slot'] 
for feature in featureList: 
    print(feature, unique_id[feature]) 

Печатается:

guinea 1.0 
bissau 2.0 
compared 3.0 
countriesthe 4.0 
population 5.0 
density 6.0 
guinea 1.0 
bissau 2.0 
similar 7.0 
iran 8.0 
afghanistan 9.0 
cameroon 10.0 
panama 11.0 
montenegro 12.0 
guinea 1.0 
belarus 13.0 
palau 14.0 
location_slot 15.0 

Мы можем сделать пару других проверок:

unique_id['cameroon'] 
# 10.0 
unique_id['this is new'] 
# 16.0 
+0

Как это работает для 'lrb' и' rrb', которые дважды появляются в моем примере? Можете ли вы включить в свой ответ, а не только включать в свой тест заранее уникальные слова? :) –

+1

@DhruvGhulati так же, как это работает для 'guinea' и' bissau' ... посмотрите на th e уникальные ключи, затем пример поиска камеры снова ... Перейдите в свой полный список функций и попробуйте запустить его - в противном случае получится очень большой ответ :) –

+0

@DhruvGhulati также - возможное преимущество этого подхода заключается в том, что вы можете сохранить его на диске и возобновить там, где вы остановились легче, чем полагаться на 'id' (которые могут отличаться по реализации Python) через сеансы ... но все работает ... –

Смежные вопросы