Проверьте, все ли числа в списке имеют одинаковый знак в Python?



Как я могу сказать, что список (или итерационный) чисел имеют один и тот же знак?



Вот мой первый (наивный) черновик:



def all_same_sign(list):

negative_count = 0

for x in list:
if x < 0:
negative_count += 1

return negative_count == 0 or negative_count == len(list)


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

Обновить



Мне пока нравятся ответы, хотя я задаюсь вопросом о производительности. Я не любитель перформанса, но я думаю, что, когда имеешь дело со списками, разумно рассмотреть представление. Для моего конкретного случая использования я не думаю, что это будет иметь большое значение, но для полноты этого вопроса я думаю, что это хорошо, чтобы обратиться к нему. Я понимаю, что функции min и max имеют производительность O(n). Два предложенных ответа до сих пор имеют производительность O(2n), в то время как моя вышеописанная процедура добавления короткого замыкания для выхода после обнаружения противоположного знака будет иметь в худшем случае производительность O(n). Мысли?

825   4  

4 ответов:

Вы можете использовать функцию all: -

>>> x = [1, 2, 3, 4, 5]

>>> all(item >= 0 for item in x) or all(item < 0 for item in x)
True

Не знаю, самый ли это питонский способ.

Как насчет:

same_sign = not min(l) < 0 < max(l)

В основном, это проверяет, является ли наименьший элемент l и наибольший элемент равными нулю.

Это не приводит к короткому замыканию, но позволяет избежать петель Python. Только сравнительный анализ может сказать, является ли это хорошим компромиссом для ваших данных (и имеет ли значение производительность этой части).

Вместо all Вы можете использовать any, так как это также приводит к короткому замыканию на первом истинном элементе:

same = lambda s: any(i >= 0 for i in s) ^ any(i < 0 for i in s)

Аналогично использованию all, Вы можете использовать any, который имеет преимущество лучшей производительности, так как он разорвет цикл при первом появлении другого знака:

def all_same_sign(lst):
    if lst[0] >= 0:
        return not any(i < 0 for i in lst)
    else:
        return not any(i >= 0 for i in lst)

Было бы немного сложно, если вы хотите рассматривать 0, как принадлежность к обеим группам:

def all_same_sign(lst):
    first = 0
    i = 0
    while first == 0:
        first = lst[i]
        i += 1
    if first > 0:
        return not any(i < 0 for i in lst)
    else:
        return not any(i > 0 for i in lst)

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

Comments

    Ничего не найдено.