Оценка истины любого типа переменной - PullRequest
0 голосов
/ 02 июня 2018

Как можно просто проверить, что некоторая переменная не является ложной, независимо от того, является ли переменная массивом, списком, целым числом или чем-то еще?Например:

import numpy as np

a = 1
b = False
c = np.array([1, 2])

def myFunction(var):
    if var:
        print('var is something, but it's not False')

myFunction(a)
myFunction(b)
myFunction(c)

Возвращает сообщение об ошибке «Значение истинности массива с более чем одним элементом неоднозначно. Используйте a.any () или a.all ().»для ц.Если я использую var.all (), то код будет работать только с массивом.Должен быть какой-то метод оценки, который не заботится о том, какой тип переменной указан.Я знаю, что мог бы использовать try, но для этого потребуется несколько строк кода, и он кажется очень непитоническим для кажущейся простой задачи.

Для некоторого контекста иногда я хочу выполнить фрагмент кода только при условии, что эта переменная действительно имеет значение.Если это не имеет значения, возможно, по умолчанию это False, тогда я хочу выполнить другой фрагмент кода.

Ответы [ 4 ]

0 голосов
/ 04 июня 2018

Отлично!Вопрос был по существу: в операторе if, как мне выполнить оценку True любого типа переменной, просто чтобы убедиться, что я еще не определил эту переменную как false?Это довольно простое решение:

def test(x):
  return type(x) != bool or x

if test(False):
    print('False will NOT cause execution')
else:
    print('False will NOT cause execution')

if test(True):
    print('True will cause execution')

if test(np.array([])):
    print('An empty array will cause execution')

if test(np.array([1, 2])):
    print('The test works for long arrays.')

print('\n')

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

def test2(x):
    if x is not None:
        return True

if test2(False):
    print('False WILL cause execution')

if test2(True):
    print('True will cause execution')

if test2(np.array([])):
    print('An empty array will cause execution')

if test2(np.array([1, 2])):
    print('The test works for long arrays.')

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

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

0 голосов
/ 02 июня 2018

Как предложил Стивен Раух, возможно с try:

def myFunction(var):
    try:
        if var==False: #If raises an exception, will jump to except
            print("var is something, and it IS False")
        else:
            print("var is something, and it's not False")
    except:
        print("var is something, and it's not False")
0 голосов
/ 03 июня 2018

Из документов Python, https://docs.python.org/3.6/library/stdtypes.html#truth-value-testing

Any object [of builtin type] can be tested for truth value, 
for use in an if or while condition or as operand of the Boolean operations below.

By default, an object is considered true unless its class defines 
either a __bool__() method that returns False or a __len__() method 
that returns zero, when called with the object.

В нем перечислены различные встроенные объекты, которые считаются false: None, False, 0, [], {} `.

Каждая переменная имеет value, то есть ссылается на объект.В Python нет такой вещи как неинициализированная переменная.Вы получите NameError, если попытаетесь использовать переменную, которая не была назначена.

None является хорошим значением default, например, в:

def foo(x, y=None):
    if y is None:
       y = 'a special value'
    ...

Массив numpy не является встроенным типом и плохо работает с этим тестированием на истинность-значение.ndarray всегда имеет значение.

Вот несколько случаев:

Массив из одного элемента независимо от размеров (0,1, ...) работает в if:

In [73]: if np.array([0]): print('yes')   # np.array(False), etc
In [74]: if np.array([1]): print('yes')
yes

Но многоэлементный массив будет выдавать ValueError независимо от значений:

In [75]: if np.array([1,2]): print('yes')
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-75-1212b980c1b6> in <module>()
----> 1 if np.array([1,2]): print('yes')

ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()

Пустой массив (0 элементов) также является особым случаем:

In [77]: if np.array([]): print('yes')
/usr/local/bin/ipython3:1: DeprecationWarning: The truth value of an empty array is ambiguous. Returning False, but in future this will result in an error. Use `array.size > 0` to check that an array is not empty.
  #!/usr/bin/python3

Это ValueError подходитчасто на ТАК.Обычно это:

if x<0:
   ...

, где x - массив.< проверяет каждое значение и создает логический массив.numpy вызывает эту ошибку, когда такой массив встречается в контексте, который ожидает скалярное логическое значение: if, and, or.

Одна из возможностей - выполнить тест is None с помощью:

if isinstance(y, np.ndarray):
    <specialized array testing>
elif y:
    <builtin False>
else:
    <truthy>
0 голосов
/ 02 июня 2018

Попробуйте это:

def test(x):
  return type(x) != bool or x
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...