2009-02-22 11 views
9

मैं श्रृंखलाएं जिनमें दशमलव या तर्कसंगत संख्या को निरूपित कर सकते हैं तैरता कोतर्कसंगत और दशमलव संख्या तारों को पायथन में तैरने के लिए कैसे परिवर्तित करें?

>>> ["0.1234", "1/2"] 
['0.1234', '1/2'] 

मैं चाहता था [.1234, 0.5] कैसे बदल सकते हैं।

>>> eval("1/2") 
0 

उत्तर

16

मैं स्ट्रिंग पार्स हैं तो रूपांतरण विफल रहता है:

eval
>>> def convert(s): 
    try: 
     return float(s) 
    except ValueError: 
     num, denom = s.split('/') 
     return float(num)/float(denom) 
... 

>>> convert("0.1234") 
0.1234 

>>> convert("1/2") 
0.5 

आम तौर पर उपयोग करते हुए, एक बुरा विचार है, क्योंकि यह एक सुरक्षा जोखिम है। विशेष रूप से यदि स्ट्रिंग का मूल्यांकन किया गया तो सिस्टम के बाहर से आया था।

+1

+1। इस मामले में eval पूरी तरह से अनावश्यक है, और मैं किसी के लिए खुश हूँ (मेरे अलावा, निश्चित रूप से) जो सही है के लिए अटक गया। –

+0

Eval एक सुरक्षा जोखिम नहीं है जब तक कि आपके सहकर्मी दुर्भावनापूर्ण समाजोपैथ न हों। आपको इस मामले में इसकी आवश्यकता नहीं है, लेकिन यह ओपन सोर्स कोड की तुलना में सुरक्षा जोखिम नहीं है। –

+0

बहुत अच्छा। स्ट्रिंग वास्तव में बाहर से है इसलिए मुझे सुरक्षित जाना है (और बुरी आदतों को नहीं सीखने की कोशिश करें)। मैं उम्मीद कर रहा था कि इसे पार्स करने की ज़रूरत नहीं है लेकिन यह बहुत बुरा नहीं है और एक आकर्षण की तरह काम करता है। – ketorin

3

/ ऑपरेटर पूर्णांक विभाजन करता है:

eval मैं क्या सोच रहा था, लेकिन कोई किस्मत है। प्रयास करें:

>>> eval("1.0*" + "1/2") 
0.5 

क्योंकि eval() संभावित खतरनाक है, तो आप हमेशा की जाँच करनी चाहिए ठीक क्या आप इसे में गुजर रहे हैं:

>>> import re 
>>> s = "1/2" 
>>> if re.match(r"\d+/\d+$", s): 
...  eval("1.0*" + s) 
... 
0.5 

हालांकि, अगर आप में एक regex के खिलाफ इनपुट मिलान की परेशानी के लिए जाना पहले स्थान पर है, तो आप के रूप में अच्छी r"(\d+)/(\d+)$" का उपयोग कर सकते अंश और हर को निकालने के लिए, विभाजन खुद करते हैं, और पूरी तरह से बचने के eval():

>>> m = re.match(r"(\d+)/(\d+)$", s) 
>>> if m: 
...  float(m.group(1))/float(m.group(2)) 
... 
0.5 
+0

धन्यवाद, eval संकेत अब के लिए अच्छा है और काम सिर्फ महान करना होगा ... सिवाय इसके कि मुझे एहसास हुआ कि मैं उठाई के रूप में एक सुरक्षित समाधान की जरूरत है बाहर। – ketorin

0

ऐसा इसलिए है क्योंकि 1 और 2 को पायथन द्वारा पूर्णांक के रूप में व्याख्या किया जाता है और फ्लोट नहीं होता है। इसे 1.0/2.0 या उसके कुछ मिश्रण होने की आवश्यकता है।

4

अपने इच्छित व्यवहार प्राप्त करने के लिए from __future__ import division का उपयोग करें। फिर, एक चुटकी में, आप की तरह

from __future__ import division 
strings = ["0.1234", "1/2", "2/3"] 
numbers = map(eval, strings) 

अपने तार के बाहर तैरता की एक सूची प्राप्त करने के लिए कुछ कर सकते हैं। यदि आप इसे "दाएं" तरीके से करना चाहते हैं, तो eval() का उपयोग न करें, बल्कि इसके बजाय एक स्ट्रिंग स्वीकार करें जो 0 स्ट्रिंग स्वीकार करता है और float() पर कॉल करता है यदि इसमें कोई स्लैश नहीं है, या स्ट्रिंग को पार्स करता है और वहां संख्यात्मक और denominator को विभाजित करता है इसमें एक स्लैश

एक तरह से यह करने के लिए:

def parse_float_string(x) 
    parts = x.split('/', 1) 
    if len(parts) == 1: 
     return float(x) 
    elif len(parts) == 2: 
     return float(parts[0])/float(parts[1]) 
    else: 
     raise ValueError 

तो बस map(parse_float_string, strings) आप अपनी सूची मिल जाएगा।

2

eval के साथ समस्या यह है कि, पाइथन में, पूर्णांक का भाग एक पूर्णांक है। तो, आपके पास कई विकल्प हैं।

from __future__ import division 

अन्य तर्कसंगत संख्या विभाजित करने के लिए है:

पहले बस पूर्णांक विभाजन वापसी तैरता बनाना है

reduce(lambda x, y: x*y, map(int, rat_str.split("/")), 1) 

कहाँ rat_str एक तर्कसंगत संख्या के साथ स्ट्रिंग है।

0

from __future__ import division के साथ सुझाव eval के साथ संयुक्त रूप से काम करेंगे।

यह शायद उनका कहना है कि सुझाव है कि eval का उपयोग नहीं करते बल्कि स्ट्रिंग पार्स ऐसा क्योंकि eval खतरनाक है लायक है: अगर वहाँ एक मनमाना स्ट्रिंग eval के लिए भेजा करने के लिए के लिए कोई रास्ता नहीं है, तो आपके सिस्टम कमजोर है । तो यह एक बुरी आदत है। (लेकिन अगर यह सिर्फ त्वरित और गंदी कोड है, यह शायद नहीं कि बड़ा एक सौदा है!)

7

के रूप में अन्य लोगों ने बताया है, का उपयोग कर eval संभवतः एक सुरक्षा जोखिम है, और निश्चित रूप से एक बुरी आदत में मिल रहा है। (यदि आप इसे exec के रूप में के रूप में जोखिम भरा है नहीं लगता है, कल्पना eval तरह ing कुछ: __import__('os').system('rm -rf /'))

हालांकि, अगर आप अजगर 2.6 या ऊपर है, तो आप ast.literal_eval, जिसके लिए स्ट्रिंग प्रदान का उपयोग कर सकते हैं:

में केवल निम्नलिखित पायथन शाब्दिक संरचनाएं हो सकती हैं: तार, संख्याएं, टुपल्स, सूचियां, डिस्केट, बूलियन, और कोई नहीं।

इस प्रकार यह काफी सुरक्षित :-)

+0

इसके बारे में नहीं पता था - धन्यवाद! –

+0

गंभीर रूप से अपमानित होने वाले सहकर्मियों के बिना उदाहरण के रूप में दुर्भावनापूर्ण कुछ कैसे निकालना संभव है? खोल के उपयोग से इवल अब सुरक्षा जोखिम नहीं है सुरक्षा जोखिम है। –

+0

उचित बिंदु..यदि आप अविश्वसनीय इनपुट से निपट नहीं रहे हैं तो eval कोई जोखिम नहीं है। मुझे लगता है कि मैं इस पोस्ट से प्रभावित हूं: http://phpxmlrpc.sourceforge.net/#security - PHP लोगों ने अपनी समस्याओं को हल करने के लिए दो बार कोशिश की, यह महसूस करने से पहले कि उन्हें eval से छुटकारा पाना पड़ा। तो ... –

6

एक अन्य विकल्प (यह भी केवल के लिए 2.6 और ऊपर) होना चाहिए fractions मॉड्यूल है।

>>> from fractions import Fraction 
>>> Fraction("0.1234") 
Fraction(617, 5000) 
>>> Fraction("1/2") 
Fraction(1, 2) 
>>> float(Fraction("0.1234")) 
0.1234 
>>> float(Fraction("1/2")) 
0.5 
1

पायथन 3 में, यह काम करना चाहिए।

>>> x = ["0.1234", "1/2"] 
>>> [eval(i) for i in x] 
[0.1234, 0.5] 
+1

ठीक है, पायथन 3 में उन्होंने '__future__ आयात प्रभाग' से डिफ़ॉल्ट बनाया ... पायथन 3 में, भविष्य अब है! – kquinn

1

sympy आपकी सहायता कर सकते हैं:

import sympy 

half = sympy.Rational('1/2') 
p1234 = sympy.Rational('0.1234') 
print '%f, %f" % (half, p1234) 
संबंधित मुद्दे

 संबंधित मुद्दे