Подтвердить что ты не робот

Python - если нет инструкции с 0.0

У меня есть вопрос относительно инструкции if not в Python 2.7.

Я написал код и использовал операторы if not. В одной части кода, который я написал, я ссылаюсь на функцию, которая включает оператор if not, чтобы определить, было ли введено необязательное ключевое слово.

Он отлично работает, за исключением случаев, когда 0.0 - значение ключевого слова. Я понимаю, это потому, что 0 является одной из вещей, которые считаются "нет". Мой код, вероятно, слишком длинный для публикации, но это аналогичный (хотя и упрощенный) пример:

def square(x=None):
    if not x:
        print "you have not entered x"
    else:
        y=x**2
        return y

list=[1, 3, 0 ,9]
output=[]


for item in list:
    y=square(item)
    output.append(y)

print output

Однако в этом случае я получил:

you have not entered x
[1, 9, None, 81]    

Где бы я хотел:

[1, 9, 0, 81]

В приведенном выше примере я мог бы использовать понимание списка, но предполагая, что хочу использовать функцию и получить желаемый результат, как я могу это сделать?

Одна мысль, что у меня была:

def square(x=None):
    if not x and not str(x).isdigit():
        print "you have not entered x"
    else:
        y=x**2
        return y

list=[1, 3, 0 ,9]
output=[]


for item in list:
    y=square(item)
    output.append(y)

print output

Это работает, но похоже, что это неуклюжий способ сделать это. Если у кого-то есть другой способ, который был бы хорош, я был бы очень благодарен.

4b9b3361

Ответ 1

Проблема

Вы понимаете это правильно. not 0 (а также not 0.0) возвращает True в Python. Простой тест можно сделать, чтобы увидеть это:

a = not 0
print(a)

Result: True

Таким образом, проблема объясняется. Эта строка:

if not x:

Необходимо изменить на что-то еще.


Решение

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


  • Для обработки всех возможных действительных случаев.

    Так как square должен, естественно, ожидать ввода числа с исключением комплексного числа и должен return ошибка в противном случае, я думаю, что лучшим решением является оценка с использованием if not isinstance(x, numbers.Number) or isinstance(x, numbers.Complex):

    def square(x=None):
        if not isinstance(x, numbers.Number) or isinstance(x, numbers.Complex): # this sums up every number type, with the exclusion of complex number
            print ("you have not entered x")
        else:
            y=x**2
            return y
    
    list=[1, 3, 0 ,9]
    output=[]
    
    for item in list:
        y=square(item)
        output.append(y)
    
    print (output)
    

    numbers.Number - абстрактный класс, чтобы проверить, является ли аргумент x числом (кредит Copperfield для указания этого).

    Выдержка из Документация по стандартной библиотеке Python объясняет, что вам нужно - за исключением сложного числа:

    класс numbers.Number

    Корень из числовой иерархии. Если вы просто хотите проверить, аргумент x является числом, не заботясь о том, какой тип, используйте isinstance (x, Number).

    Но вы не хотите, чтобы ввод был сложным числом. Поэтому просто опустите его, используя or isinstance(x, numbers.Complex)

    Таким образом, вы пишете definition square точно так, как вы хочу это. Это решение, я думаю, является лучшим решением по его полнота.


  1. Для обработки только тех типов данных, которые вы хотите обрабатывать.

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

    if not instance(x, int): #just handle int
    if not instance(x, (int, float)): #just handle int and float
    if not instance(x, (numbers.Integral, numbers.Rational)): #just handle integral and rational, not real or complex
    

    Вы можете легко изменить/расширить условие выше для разных данных типы, которые вы хотите включить или исключить, - в соответствии с вашими необходимость. Это решение, я думаю, является вторым лучшим благодаря его для проверки достоверности.

    (Код выше делается более питоническим способом, как предлагается cat)


  1. Не обрабатывать невозможные случаи: вы знаете, что пользователи не будут помещать в качестве ввода.

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

    if not isinstance(x, numbers.Number): # this is ok, because the user would not put up complex number
    

    Это решение, я думаю, является третьим лучшим благодаря one простейшей, но мощной проверки.

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


  1. Чтобы обрабатывать ошибки ввода только для известных возможных входов, которые могут вызывать ошибки.

    Например, если вы знаете, что x всегда int или None - и, следовательно, единственная возможная ошибка ввода - это None - тогда мы можем просто написать логику, чтобы избежать оценки y только тогда, когда x None выглядит следующим образом:

    def square(x=None):
        if x is None:
            print ("you have not entered x")
        else:
           y=x**2
           return y
    
    list=[1, 3, 0 ,9]
    output=[]
    
    for item in list:
        y=square(item)
        output.append(y)
    
    print (output)
    

    Это решение имеет силу простейшего.

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

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

    if not x and not str(x).isdigit():
    

    Хорошо, за исключением того, что примерное решение проще


Учитывая ваше дело, вы можете использовать любое решение выше, чтобы получить:

 [1, 9, 0, 81]

(Side Note: Я пытаюсь отформатировать решения, чтобы они выглядели как "канонические решения" для удобства чтения. Таким образом, те, у кого есть те же вопросы и которые посещают эту страницу в будущем, смогут найти решения более всеобъемлющий и читаемый)

Ответ 2

Поскольку вы используете None для сигнала "этот параметр не установлен", то это именно то, что вы должны проверить для использования ключевого слова is:

def square(x=None):
    if x is None:
        print "you have not entered x"
    else:
        y=x**2
        return y

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

Ответ 3

if x is None:
   print 'x is None'

Ответ 4

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

if x is None:
    ...

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

if isinstance(x, (int, float, ...)):
    ...

... представляют другие допустимые классы (возможно, Decimal или Fractions).

Итак, вы можете написать это как:

if x is not None and isinstance(x, (int, float)):
     return x**2
else:
     print "you have not entered x"

Поскольку None не является int и a float, вы также можете опустить первое условие и написать:

if isinstance(x, (int, float)):
     ...

Ответ 5

Если вы можете идентифицировать один тип, с которым должен быть совместим все входные данные, вы можете преобразовать его и обработать исключение:

def square(x=None):
    try:
        return float(x)**2
    except TypeError:
        print "You did not enter a real number"
        return None # Explicit is better than implicit

Это имеет несколько преимуществ.

  • Он обеспечивает, чтобы все, что отправляет пользователь, совместимо с float. Это может быть любое число, строка, содержащая число ('5.0'), или все, что может быть преобразовано в float. (float экземпляры возвращаются без изменений.)
  • Это просто. В вашем методе нет странной магии. Вы не нарушаете утиную печать. Вы просто выполняете свои требования, чтобы заставить работу работать правильно.
  • Он не уязвим для gotchas, связанного с фактической проверкой типа. Ваши абоненты могут рассказать вам, как их настраиваемый тип преобразуется в float. Python предоставляет магический метод __float__, поэтому, если ваши пользователи имеют экзотические типы и должны использовать вашу функцию, они не потоплены.
  • Это идиоматично. Опытные программисты на Python ожидают такого рода код; это следует принципу "проще просить прощения, чем разрешение".

В стороне (возможно):

Если None является недопустимым значением, не делайте его значением по умолчанию. Просто заставьте вызывающего абонента ввести ввод:

def square(x):
    try:
        return float(x)**2
    except TypeError:
        print "You did not enter a real number"
        return None

Ответ 6

U может обрабатывать исключение здесь. Сделайте такой код

def square(x):
    if not x:
        print "you have not entered x"
    else:
        try:
            int(y)=x**2
            return y
        except TypeError:
            pass


list=[1, 3, 0 ,9]
output=[]