Отзыв о реализации функции, которая сравнивает целочисленные знаки в Python - PullRequest
3 голосов
/ 30 декабря 2010

Я сделал небольшую функцию, которая, учитывая кортеж, сравнивает, если все элементы в этом кортеже имеют один и тот же знак.

Например, кортеж = [-1, -4, -6, -8] - это хорошо, а [-1, -4, 12, -8] - плохо. Я не уверен, что сделал самую умную реализацию, поэтому я знаю, что это место, чтобы спросить.

def check_consistent_categories(queryset):
    try:
        first_item = queryset[0].amount

        if first_item < 0:
            for item in queryset:
                if item > 0:
                    return False
            return True
        else:
            for item in queryset:
                if item < 0:
                    return False
            return True
    except:
        return False

Ответы [ 9 ]

14 голосов
/ 30 декабря 2010

Это может помочь вам:

def all_same_sign(ints):
    return all(x < 0 for x in ints) or all(x > 0 for x in ints)

Вы можете изменить <и> на <= и> = в зависимости от того, как вы хотите относиться к 0.

3 голосов
/ 30 декабря 2010

После решения @ EOL, но работает без индексации списка или многократного повторения.

def all_same_sign(sequence):
    items = iter(sequence)
    try:
        first = items.next() > 0
    except StopIteration:
        return True
    return all((item > 0) == first for item in items)

Это также произошло со мной, но не использует все / любое короткое замыкание:

def all_same_sign(sequence):
    return len(set(item > 0 for item in sequence)) <= 1
1 голос
/ 01 января 2011
def all_same_sign(iterable):
    # Works with any iterable producing any items that can be compared to zero.
    # Iterates through the input no more than once, and this fact is immediately
    # obvious from the code.
    # Exits as soon as a bad combination has been detected.
    pos = neg = zero = False
    for item in iterable:
        if item > 0:
            pos = True
        elif item < 0:
            neg = True
        else:
            zero = True
        # Adjust the following statement if a different
        # treatment of zero is required.
        # Redundant parentheses added for clarity.
        if (pos and neg) or zero:
            return False
    return True
1 голос
/ 30 декабря 2010

Вот тот, который отлично работает с генераторами и т. Д. Тоже

def all_same_sign(ints):
    ints = iter(ints)
    first_is_positive = next(ints) > 0
    return all( (x>0) == first_is_positive for x in ints)

Если ints пусто, вы получаете исключение StopIteration.

Эта версия группирует 0 с отрицательными числами. Используйте >=, если вы хотите группировать с положительными числами вместо

1 голос
/ 30 декабря 2010

Почему бы не воспользоваться тем фактом, что если все числа имеют один и тот же знак, то сумма абсолютного значения каждого отдельного числа будет равна абсолютному значению суммы каждого числа?

def check_sign(queryset):
    return abs(sum(queryset)) == sum(map(abs, queryset))

Пример, показывающий детали математики

Случай 1: Все числа имеют одинаковый знак

a = (-1, -4, -8)
sum(a) = -13
abs(sum(a)) = 13        # the absolute value of the tuple's sum
map(abs, a) = [1, 4, 8]
sum(map(abs, a)) = 13   # the tuple's sum of each element's absolute value

Оба метода дают 13, поэтому знаки одинаковы.

Случай 2: Не все числа имеют одинаковый знак

b = (-1, 4, 8)
sum(b) = 11
abs(sum(b)) = 11        # the absolute value of the tuple's sum 
map(abs, b) = [1, 4, 8]
sum(map(abs, b)) = 13   # the tuple's sum of each element's absolute value

Методы дают разные числа (11 и 13), поэтому знаки не все одинаковы.

1 голос
/ 30 декабря 2010

Всего один неродственный гниль, поскольку вы делаете это:

try:
    [...]
except:
    [...]

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

try:
    [...]
except IndexError:
    # Handle out of index
except IOError:
    # Handle I/O error

и т. д.Имейте это в виду при написании больших приложений на Python.

1 голос
/ 30 декабря 2010

Вот хороший питонский способ сделать это (используя all()):

from math import copysign

sign = lambda x: copysign(1, x)  # Sign function

def check_consistent_categories(sequence):
    main_sign = sign(sequence[0])
    return all(sign(y) == main_sign for y in sequence)

(для Python 2.6+, в котором появилась функция math.copysign()). Это решение считает, что 0 является положительным.

Решение Марка Байерса, однако, более гибкое и, возможно, более разборчивое.

0 голосов
/ 31 декабря 2010

Использование принципала, который умножает ваши числа, дает положительный результат, если они все одинаковые, иначе отрицательный,

import operator

def all_same_sign(intlist):
    return reduce(operator.mul, intlist) > 0

>>> all_same_sign([-1, -4, -6, -8])
True
>>> all_same_sign([-1, -4, 12, -8])
False

Это не обрабатывает нули, хотя ...

0 голосов
/ 30 декабря 2010

Если ваши номера отсортированы, вам нужно только сравнить концы.Если нет, вы можете отсортировать их:

def same_sign(numbers):
    numbers = sorted(numbers)
    #if numbers[0]==0: return True                Uncomment if you consider 0 positive
    if numbers[0]*numbers[-1]>0: return True
    return False

Если вы измените это значение на >=0, ноль будет считаться нейтральным знаком.Я не уверен, что это лучшая реализация, чем текущие ответы, но она может быть быстрее для больших наборов данных.

...