Используйте регулярные выражения для определения типа переменной в Python - PullRequest
0 голосов
/ 02 февраля 2019

Я новичок в python и мне интересно, есть ли более эффективные способы решения этой домашней задачи:

Напишите функцию mytype (v), которая выполняет то же действие, что и type (), и может распознатьцелые числа, числа с плавающей запятой, строки и списки.Сделайте это, используя сначала str (v), а затем читая строку.Предположим, что списки могут содержать только числа (не строки, другие списки и т. Д.), И предположим, что строки могут быть чем угодно, кроме целых чисел, чисел с плавающей точкой или списка.

Проблема требует использования регулярных выражений.Вот то, что я имею до сих пор, и это работает, насколько мне известно.Мне интересно, существуют ли способы сделать это БЕЗ так много утверждений if?то есть более кратким или более эффективным?

import re 

def mytype(v):
   s = str(v)
   # Check if list
   list_regex = re.compile(r'[\[\]]')
   l = re.findall(list_regex, s)
   if l:
      return "<type 'list'>"
   # Check if float
   float_regex = re.compile(r'[0-9]+\.')
   f = re.findall(float_regex, s)
   if f: 
      return "<type 'float'>"
   # Check if int
   int_regex = re.compile(r'[0-9]+')
   i = re.findall(int_regex, s)
   if i:
      return "<type 'int'>"
   # Check if string
   str_regex = re.compile(r'[a-zA-Z]+')
   t = re.findall(str_regex, s)
   if t:
      return "<type 'string'>"


x = 5
y = 5.5
z= .99
string = "hsjjsRHJSK"
li = [1.1,2,3.2,4,5]


print mytype(x) # <type 'int'>
print mytype(y) # <type 'float'>
print mytype(z) # <type 'float'>
print mytype(string) # <type 'string'>
print mytype(li) # <type 'list'>

Ответы [ 2 ]

0 голосов
/ 02 февраля 2019

Мне интересно, существуют ли способы сделать это БЕЗ так много утверждений if?то есть более кратким или более эффективным?

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

def mytype(v):
    s = str(v)

    # Check if list
    if re.search(r'[\[\]]', s):
        return "<type 'list'>"

    # Check if float
    if re.search(r'[\d]+\.', s): 
        return "<type 'float'>"

    # Check if int
    if re.search(r'[\d]+', s):
        return "<type 'int'>"

    # Assume strings are anything that's not an int, float or list
    return "<type 'string'>"

Это еще до рассмотрения ваших регулярных выражений.Вам не нужно звонить re.compile() для этого использования.Ваш list тест может легко поймать dict, но dict не соответствует вашим требованиям.z = .99 работает только потому, что к моменту превращения в строку это "0.99".Фактическая строка ".99" не прошла бы ваш float тест.В ваших тестах float и int есть зависимость порядка - это следует прокомментировать.

0 голосов
/ 02 февраля 2019

Используйте group для сопоставления и получения захваченного имени группы и канала | в регулярном выражении.

регулярного выражения : (?P<list>\[\[^\]\]+\])|(?P<float>\d*\.\d+)|(?P<int>\d+)|(?P<string>\[a-zA-Z\]+)

Подробности:

  • | или
  • (?P<>) группа захвата с именем Python

код Python:

def mytype(v):
    s = str(v)
    regex = re.compile(r'(?P<list>\[[^]]+\])|(?P<float>\d*\.\d+)|(?P<int>\d+)|(?P<string>[a-zA-Z]+)')
    return  r"<type '%s'>" % regex.search(s).lastgroup

Вход:

print(mytype(5))
print(mytype(5.5))
print(mytype(.99))
print(mytype("hsjjsRHJSK"))
print(mytype([1.1,2,3.2,4,5]))

Выход:

<type 'int'>
<type 'float'>
<type 'float'>
<type 'string'>
<type 'list'>

Код демонстрационный

...