2014-01-16 4 views
1

У меня есть список поплавков, сгенерированных из структуры данных, которая представляет собой список словарей - т. Е. Я повторил весь список и выбрал для определенных значений в данном словаре. Теперь я хочу сделать что-то с этими точками данных, для чего мне нужна ссылка на исходную позицию. Я попытался просто использовать точку данных в качестве ключа, но после попытки и неудачи я сделал некоторые рытье и понял, что поплавки не точно представлены из-за того, как работают компьютеры.Индексирование значений float в Python

Итак, что мне нужно каким-то образом, чтобы присвоить уникальное значение для каждого словаря в списке, например:

list = [...] 
vallist = [] 
index = {} 
for i in range(0, len(list)): 
value = i+0.123 
vallist.append(value) 
index[value] = i 

За исключением I, очевидно, нужно присвоить каждое значение уникального элемент, чтобы быть в состоянии указать назад к их позиции в объекте списка. Я предполагаю, что могу создать новый объект, называемый «valuelist» или что-то еще, а затем int над этим, но это похоже на то, что, вероятно, имеет очевидное обходное решение, которое я просто слишком толстый, чтобы понять.

Чтобы повторить, я хочу, чтобы значения возвращались в исходное положение в списке - в моей структуре данных мой список содержит тонну словарей, а способ, которым я его обрабатываю, несколько сложнее , поэтому я как бы застрял с моей непрактичной структурой.

Спасибо!

ответ

2

Во-первых, давайте рассмотрим проблемы, связанные с использованием с плавающей запятой.

Поплавки точно не представлены из-за способа работы компьютеров.

Номера с плавающей запятой точно представлены в компьютерах. Существуют, однако, некоторые ограничения:

  • Разрешение конечное. Невозможно представить иррациональное число в конечной памяти, а типичные плавающие точки могут представлять только пару десятков цифр.
  • Некоторые десятичные числа (base10) have no exact representation in binary. Например, 0,1 не может быть точно представлено в базе 2. Запуск "{0:.20f}".format(0.1) в python вернет 0.10000000000000000555.

Теперь, в зависимости от источника ваших номеров и вида вычислений, которые вы хотите выполнить, существуют различные возможные варианты их индексирования.

Для номеров, которые могут быть описаны точно в base10, вы можете использовать Decimal. Это представляет собой число в base10 именно:

>>> from decimal import Decimal 
>>> "{0:.20f}".format(Decimal('0.1')) 
'0.10000000000000000000' 

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

Обратите внимание, что если вы используете десятичные знаки или дроби, вам нужно будет использовать их как можно скорее в своей обработке.Преобразование из плавающей точкой в ​​десятичной/фракции на поздних стадиях поражения своей цели - вы не можете получить данные, которые не существуют:

>>> "{0:.20f}".format(Decimal('0.1')) 
'0.10000000000000000000' 
>>> "{0:.20f}".format(Decimal(0.1)) 
'0.10000000000000000555' 

Кроме того, используя десятичные или фракции придут на значительные потери производительности. Для серьезного хруста числа вы хотите всегда использовать поплавок, или даже integers in their place

Наконец, если ваши номера иррациональные, или если вы получаете индексации злоключения даже при использовании десятичных или фракции, ваш лучший выбор, вероятно, индексации округленные версии номеров. При необходимости используйте buckets. collections.defaultdict могут быть полезны для этого.

Вы можете также сохранить дерево, или использовать binary search над списком с пользовательской функцией сравнения, но вы не будете иметь O(1) поиск

+0

Похоже, что я за! Я должен был знать, что у Python будет модуль для этого. Благодаря! – user3034187

1

Если я правильно понял, вы создали список поплавков, каждый из которых содержит один из диктонов в исходном списке. Вместо того, чтобы генерировать список float, почему бы не сгенерировать список 2-tuples, являющийся float, и соответствующий словарь-список-индекс ...

+0

Вот что я пытался на начальном этапе, но есть очень маленькие неточности в том, как значений с плавающей точкой , поэтому я получаю ключи, если я попытаюсь использовать их в качестве словарных клавиш, например. e. В принципе, он выполняет итерацию по первой, например, сотням значений, а затем находит что-то, что было отключено значением 0.000000001 или что-то еще, и возвращает сообщение об ошибке. – user3034187

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