python - لغة - اوامر بايثون
كيف يمكنني تحليل سلسلة إلى تعويم أو int في Python؟ (15)
في Python ، كيف يمكنني تحليل سلسلة رقمية مثل "545.2222" إلى قيمة float المطابقة لها ، 542.2222؟ أو تحليل السلسلة "31" إلى عدد صحيح ، 31؟ أنا فقط أريد أن أعرف كيفية تحليل سلسلة تعويم إلى تعويم ، و (بشكل منفصل) سلسلة Int إلى كثافة العمليات.
من الجيد أن تطلب القيام بهذه بشكل منفصل. إذا كنت تقوم بخلطها ، فربما تكون جاهزًا للمشكلات لاحقًا. الجواب البسيط هو:
"545.2222"
للتعويم:
>>> float("545.2222")
545.2222
"31"
إلى عدد صحيح:
>>> int("31")
31
التحويلات الأخرى ، النتوءات من وإلى السلاسل والحروف:
التحويلات من قواعد مختلفة ، ويجب أن تعرف القاعدة مقدمًا (10 هو الإعداد الافتراضي). لاحظ أنه يمكنك بادئتها مع ما تتوقعه بايثون من قيمها الحرفية (انظر أدناه) أو إزالة البادئة:
>>> int("0b11111", 2)
31
>>> int("11111", 2)
31
>>> int('0o37', 8)
31
>>> int('37', 8)
31
>>> int('0x1f', 16)
31
>>> int('1f', 16)
31
إذا كنت لا تعرف القاعدة مقدمًا ، لكنك تعلم أنها ستحصل على البادئة الصحيحة ، يمكن أن تستنتج بايثون ذلك إذا كنت تمرر 0
كقاعدة:
>>> int("0b11111", 0)
31
>>> int('0o37', 0)
31
>>> int('0x1f', 0)
31
عشري غير عشري (أي عدد صحيح) من قواعد أخرى
إذا كان الدافع الخاص بك هو أن يكون رمزك الخاص بوضوح يمثل قيمًا محددة مشفرة ، قد لا تحتاج إلى التحويل من القواعد - يمكنك أن تدع بيثون تفعل ذلك نيابة عنك تلقائيًا باستخدام الصيغة الصحيحة.
يمكنك استخدام بادئات apropos للحصول على التحويل التلقائي إلى الأعداد الصحيحة باستخدام القيم الحرفية التالية . هذه صالحة لبيثون 2 و 3:
ثنائي ، البادئة 0b
>>> 0b11111
31
أوكتال ، البادئة 0o
>>> 0o37
31
سداسي عشري ، البادئة 0x
>>> 0x1f
31
يمكن أن يكون ذلك مفيدًا عند وصف العلامات الثنائية أو أذونات الملفات في التعليمة البرمجية أو القيم السداسية للألوان - على سبيل المثال ، ملاحظة عدم وجود علامات اقتباس:
>>> 0b10101 # binary flags
21
>>> 0o755 # read, write, execute perms for owner, read & ex for group & others
493
>>> 0xffffff # the color, white, max values for red, green, and blue
16777215
جعل غامضة بيثون 2 الثمانية متوافق مع بيثون 3
إذا رأيت عددًا صحيحًا يبدأ بـ 0 ، في Python 2 ، فهذا يعني (موقوف) بناء جملة ثماني.
>>> 037
31
إنه أمر سيئ لأنه يبدو أن القيمة يجب أن تكون 37
. حتى في Python 3 ، فإنه يرفع الآن SyntaxError
:
>>> 037
File "<stdin>", line 1
037
^
SyntaxError: invalid token
قم بتحويل octals Python 2 إلى الثمانيات التي تعمل في كل من 2 و 3 باستخدام البادئة 0o
:
>>> 0o37
31
في Python ، كيف يمكنني تحليل سلسلة رقمية مثل "545.2222"
إلى قيمة float المطابقة لها ، 542.2222
؟ أو تحليل السلسلة "31"
إلى عدد صحيح ، 31
؟
أنا فقط أريد أن أعرف كيفية تحليل string
تعويم إلى float
، و (بشكل منفصل) string
Int إلى int
.
التطويع والفواصل
يجب مراعاة إمكانية وجود فواصل في تمثيل سلسلة من الأرقام ، لحالات مثل float("545,545.2222")
التي float("545,545.2222")
استثناءً. بدلاً من ذلك ، استخدم الطرق في locale
لتحويل السلاسل إلى أرقام وتفسير الفواصل بشكل صحيح. تحول طريقة locale.atof
إلى تعويم في خطوة واحدة بمجرد تعيين الإعدادات المحلية لاتفاقية الأرقام المطلوبة.
المثال 1 - اصطلاحات رقم الولايات المتحدة
في الولايات المتحدة والمملكة المتحدة ، يمكن استخدام الفواصل كفاصل الآلاف. في هذا المثال مع اللغة الأمريكية ، تتم معالجة الفاصلة بشكل صحيح كفاصل:
>>> import locale
>>> a = u'545,545.2222'
>>> locale.setlocale(locale.LC_ALL, 'en_US.UTF-8')
'en_US.UTF-8'
>>> locale.atof(a)
545545.2222
>>> int(locale.atof(a))
545545
>>>
المثال 2 - اتفاقيات الأرقام الأوروبية
في غالبية بلدان العالم ، يتم استخدام الفواصل للعلامات العشرية بدلاً من النقاط. في هذا المثال مع اللغة الفرنسية ، يتم معالجة الفاصلة كعلامة عشرية بشكل صحيح:
>>> import locale
>>> b = u'545,2222'
>>> locale.setlocale(locale.LC_ALL, 'fr_FR')
'fr_FR'
>>> locale.atof(b)
545.2222
تتوفر أيضًا الطريقة locale.atoi
، ولكن يجب أن تكون الوسيطة عددًا صحيحًا.
أنا استخدم هذه الوظيفة لذلك
import ast
def parse_str(s):
try:
return ast.literal_eval(str(s))
except:
return
سيقوم بتحويل السلسلة إلى نوعه
value = parse_str('1') # Returns Integer
value = parse_str('1.5') # Returns Float
أنا مندهش لا أحد ذكر regex لأنه في بعض الأحيان يجب إعداد سلسلة وتطبيع قبل الصب إلى الرقم
import re
def parseNumber(value, as_int=False):
try:
number = float(re.sub('[^.\-\d]', '', value))
if as_int:
return int(number + 0.5)
else:
return number
except ValueError:
return float('nan') # or None if you wish
الاستعمال:
parseNumber('13,345')
> 13345.0
parseNumber('- 123 000')
> -123000.0
parseNumber('99999\n')
> 99999.0
وبالمناسبة ، شيء للتحقق من أن لديك رقمًا:
import numbers
def is_number(value):
return isinstance(value, numbers.Number)
# will work with int, float, long, Decimal
إليك تفسير آخر لسؤالك (تلميح: إنه غامض). من الممكن أنك تبحث عن شيء كهذا:
def parseIntOrFloat( aString ):
return eval( aString )
يعمل مثل هذا ...
>>> parseIntOrFloat("545.2222")
545.22220000000004
>>> parseIntOrFloat("545")
545
من الناحية النظرية ، هناك ثغرة أمنية. يمكن أن تكون السلسلة ، على سبيل المثال "import os; os.abort()"
. ومع ذلك ، فبدون أية خلفية عن المكان الذي تأتي منه السلسلة ، فإن الاحتمال هو تكهنات نظرية. نظرًا لأن السؤال غامض ، فليس واضحًا تمامًا ما إذا كان هذا الثغرة موجودة بالفعل أم لا.
إن المستخدمين codelogic و harley صحيحين ، ولكن ضع في اعتبارك إذا كنت تعرف أن السلسلة عبارة عن عدد صحيح (على سبيل المثال ، 545) يمكنك الاتصال بـ int ("545") دون الصب الأول للتعويم.
إذا كانت السلاسل الخاصة بك في قائمة ، فيمكنك استخدام وظيفة الخريطة أيضًا.
>>> x = ["545.0", "545.6", "999.2"]
>>> map(float, x)
[545.0, 545.60000000000002, 999.20000000000005]
>>>
من الجيد فقط إذا كانوا من نفس النوع.
استعمال:
def num(s):
try:
for each in s:
yield int(each)
except ValueError:
yield float(each)
a = num(["123.55","345","44"])
print a.next()
print a.next()
هذه هي الطريقة الأسطورية التي يمكنني الخروج بها.
تتمتع بايثون بمرونة كبيرة في التحليل في إحدى الخطوط.
str = "545.2222"
print ("int: ", + int(float(a)))
print ("float: ", +(float(a)))
يبدو السؤال قديمًا بعض الشيء. ولكن اسمحوا لي أن أقترح وظيفة ، parseStr ، مما يجعل شيئا مشابها ، وهذا هو ، إرجاع عدد صحيح أو طفو وإذا كان لا يمكن تحويل سلسلة ASCII معينة إلى أي منها ، فإنه يعيدها دون مساس. قد يتم تعديل الكود بالطبع للقيام بما تريد فقط:
>>> import string
>>> parseStr = lambda x: x.isalpha() and x or x.isdigit() and \
... int(x) or x.isalnum() and x or \
... len(set(string.punctuation).intersection(x)) == 1 and \
... x.count('.') == 1 and float(x) or x
>>> parseStr('123')
123
>>> parseStr('123.3')
123.3
>>> parseStr('3HC1')
'3HC1'
>>> parseStr('12.e5')
1200000.0
>>> parseStr('12$5')
'12$5'
>>> parseStr('12.2.2')
'12.2.2'
يجب أن تأخذ في الاعتبار التقريب للقيام بذلك بشكل صحيح.
I int int (5.1) => 5 int (5.6) => 5 - خاطئ ، يجب أن يكون 6 حتى نقوم int (5.6 + 0.5) => 6
def convert(n):
try:
return int(n)
except ValueError:
return float(n + 0.5)
float("545.2222")
و int(float("545.2222"))
هذه نسخة مصححة من https://.com/a/33017514/5973334
سيحاول هذا تحليل سلسلة وإرجاع إما int
أو float
اعتماداً على ما يمثل السلسلة. قد ترتفع الاستثناءات أو لديها بعض السلوك غير المتوقع .
def get_int_or_float(v):
number_as_float = float(v)
number_as_int = int(number_as_float)
return number_as_int if number_as_float == number_as_int else
number_as_float
def get_int_or_float(v):
number_as_float = float(v)
number_as_int = int(number_as_float)
return number_as_int if number_as_float == number_as_int else number_as_float
def num(s):
try:
return int(s)
except ValueError:
return float(s)
float(x) if '.' in x else int(x)