2017-02-20 24 views
0

У меня есть строка, которая является список как этотPython, как eval строка списка с точностью до десятичной?

list_str = '[148654.08425925925, 148656.99994212962, 148658.08229166668, 148661.0020601852]' 

тогда я использую Eval(), чтобы преобразовать его в реальный объект списка в Python

print eval(list_str) 

Однако выход округляется, который я не» t want

0 = {float} 148654.084259 
1 = {float} 148656.999942 
2 = {float} 148658.082292 
3 = {float} 148661.00206 

Как я могу заставить его сохранять значения как в String (десятичный с точностью)?

мне нужно использовать Eval(), так как он будет использовать другие операции в этом списке, а

+2

Никогда не называйте переменные, такие как 'list' и т. Д. Теперь вы не можете вызывать' list (..) 'после этого оператора. –

+0

Кроме того, мы говорим о python-2.x или python-3.x? –

+0

это пример, который поможет вам понять, спасибо в любом случае. –

ответ

0

Использования Десятичной питона

from decimal import * 
mlist = '[148654.08425925925, 148656.99994212962, 148658.08229166668, 148661.0020601852]' 
mlisttrim = mlist[1:-1] 
l = [] 
for i in mlisttrim.split(', '): 
    l.append(Decimal(i)) 
print l 
+0

Мне нужно использовать eval(), потому что он также будет использовать другую операцию в этом списке. –

+1

@ BằngRikimaru, никогда не используйте 'eval()', если вы не уверены, что вам нужно. Он может запускать произвольный код. Вы почти никогда не нуждаетесь в этом. Вместо этого используйте ['ast.literal_eval()'] (https://docs.python.org/3/library/ast.html?highlight=ast.literal_eval#ast.literal_eval). – Chris

+0

@ Крис да, он может что-то изменить, у меня такая же идея, но мне сначала нужно решить эту проблему с десятичной точностью, спасибо. –

0

floats представлены двоичными дробями и есть потери точности при преобразовании в и из десятичного представления с точками, которое вы используете (see here). Питон decimal package реализует десятичную арифметику с плавающей запятой и не имеет этого ограничения.

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

>>> import decimal 
>>> import re 
>>> list_str = '[148654.08425925925, 148656.99994212962, 148658.08229166668, 148661.0020601852]' 
>>> items = [decimal.Decimal(x) for x in re.findall(r'\d+\.?\d*', list_str)] 
>>> items 
[Decimal('148654.08425925925'), Decimal('148656.99994212962'), Decimal('148658.08229166668'), Decimal('148661.0020601852')] 
>>> 
+0

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

1

Хотя может быть потеря точности с плавающей точкой, нет никакой потери точности здесь, учитывая, что она выглядит как строка была сгенерирована из списка Python поплавков, чтобы начать с. Обратите внимание, что ast.literal_eval рекомендуется более eval, однако:

>>> list_str = '[148654.08425925925, 148656.99994212962, 148658.08229166668, 148661.0020601852]' 
>>> import ast 
>>> L = ast.literal_eval(list_str) 
>>> L 
[148654.08425925925, 148656.99994212962, 148658.08229166668, 148661.0020601852] 

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

>>> for f in L: 
...  print '{:.11f}'.format(f) 
...  
148654.08425925925 
148656.99994212962 
148658.08229166668 
148661.00206018519 

Я также рекомендую посмотреть на pickle или json модули для сохранения списка в первую очередь, чтобы избежать использования eval или даже ast.literal_eval.

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