Страницы

Поиск по вопросам

Показаны сообщения с ярлыком max. Показать все сообщения
Показаны сообщения с ярлыком max. Показать все сообщения

суббота, 28 декабря 2019 г.

Можно ли из одного Stream достать сразу и min() и max()?

#java #java_stream #max #java_9 #min


Пусть есть IntStream, возможно ли получить из него допустим массив или лист, в котором
будут 2 значения min и max стрима? Либо можно ли вообще каким-то образом вызвать терминальный
метод на стрим больше 1 раза?
    


Ответы

Ответ 1



IntSummaryStatistics stats = IntStream.range(1, 100) .summaryStatistics(); int min = stats.getMin(); int max = stats.getMax();

Ответ 2



Можно создать коллектор, находящий минимальный и максимальный элемент. Вообще рекомендую способ с IntSummaryStatistics, но коллектор можно сделать. Коллектор: static Collector> minMax( Comparator comparator, BiFunction finisher){ class Accumulator{ T min; T max; boolean present; void add(T value){ if(present){ if(comparator.compare(value, min) <0) min= value; if(comparator.compare(value, max) >0) max= value; }else { min=max=value; present=true; } } Accumulator combiner(Accumulator other){ if(!other.present) return this; if(!present) return other; if(comparator.compare(other.min, min) <0) min=other.min; if(comparator.compare(other.max, max) >0) max=other.max; return this; } } return Collector.of(Accumulator::new, Accumulator::add, Accumulator::combiner, accumulator -> accumulator.present ? Optional.of(finisher.apply(accumulator.min, accumulator.max)) : Optional.empty()); } Его использование может выглядит вот так: Integer [] arr= IntStream.of(12, 45, 23, 68). boxed(). collect( minMax( Integer::compareTo, (min, max) -> new Integer[] {min, max})).get(); for (Integer i: arr) { System.out.println(i); } Можно сделать чтоб возвращал List: List list =IntStream.of(12, 45, 23, 68). boxed(). collect( minMax( Integer::compareTo, (min, max) -> Arrays.asList(min, max))).get(); list.iterator().forEachRemaining(System.out::println);

Ответ 3



Нет, стрим позволяет пройтись по нему только один раз (а если нижележащий сплитератор выстрелит, то можно и вообще не дойти до конца). Но это не значит, что вы не можете одновременно собирать и максимум, и минимум: private static class Result { private Integer minimum; private Integer maximum; public Integer getMinimum() { return minimum; } public Integer getMaximum() { return maximum; } public synchronized Result update(int value) { if (minimum == null || minimum > value) { minimum = value; } if (maximum == null || maximum < value) { maximum = value; } return this; } public synchronized void combine(Result other) { if (other.getMinimum() != null) { update(other.getMinimum()); } if (other.getMaximum() != null) { update(other.getMaximum()); } } @Override public String toString() { return "Result {minimum=" + minimum + ", maximum=" + maximum + "}"; } } public static Result compute(IntStream stream) { return stream.collect(Result::new, Result::update, Result::combine); }

Ответ 4



Вот Ваш массив: int[] miniMax = IntStream.range(1, 11).collect(() -> { return new int[] { Integer.MAX_VALUE, Integer.MIN_VALUE }; }, (t, value) -> { if (t[0] > value) t[0] = value; if (t[1] < value) t[1] = value; }, (t, u) -> { if (t[0] > u[0]) t[0] = u[0]; if (t[1] < u[1]) t[1] = u[1]; }); int min = miniMax[0]; int max = miniMax[1]; Если попадётся пустой stream, то получится невероятный результат min == 2147483647 и max == -2147483648 Условие, что получено именно то, что надо: min <= max

понедельник, 9 декабря 2019 г.

Зачем нужен вызов “-> max(a,b)” при создании функции?

#python #python_3x #функции #max


Нашёл такой пример: 

def function(a:int,b:str,c:list) -> max(2,3):


Зачем используется -> max(...)?
    


Ответы

Ответ 1



В данной строке def function(a:int,b:str,c:list) -> max(2,3): :int, :str, :list, -> max(2,3) - это аннотации. Впервые они предлагаются к введению в Python в PEP 3107, но их назначение четко не регламентировалось (их интерпретация возлагалась на авторов сторонних инструментов). В качестве аннотации может использоваться любое синтаксически верное выражение Python. При запуске кода интерпретатором выражения, используемые в качестве аннотации, исполняются (поэтому могут вызывать ошибки во время исполнения, например выражение def f() -> max(None, 1): pass вызовет ошибку TypeError, пример от jfs), но никаким специальным образом интерпретатором не обрабатываются (т.е., например, интерпретатор сам не проверяет типы). Позже было более четко зафиксировано использование аннотаций как аннотаций типов (PEP 484), т.е. после аргументов функции через двоеточие пишем предполагаемый тип аргумента, после -> пишем тип возвращаемого значения функции. Опять же, интерпретатор их игнорирует, но аннотации типов могут использоваться такими инструментами как mypy или встроенным в PyCharm статическим анализатором кода, чтобы понимать, что в функцию передано (или возвращено) значение не того типа, которое предполагалось, и отображать это как ошибку или предупреждение. -> max(2,3) с моей точки зрения не несет никакой смысловой нагрузки. Это не аннотация типа, а просто аннотация. Что имел в виду автор примера - загадка. Скорее всего это просто пример использования аннотаций. Программно получить доступ к аннотациям функции можно через атрибут функции __annotations__: def function(a:int,b:str,c:list) -> max(2,3): pass print(function.__annotations__) Результат: {'a': , 'return': 3, 'c': , 'b': } Здесь видны прописанные для аргументов типы, и видно, что выражение max(2,3) вычислилось, поэтому в качестве аннотации для возвращаемого значения записалось просто 3.

Ответ 2



Как мы можем видеть, эта функция может принимать число - a:int, строку - b:str и список - c:list. Функция max() возвращает наибольшее значение. Это можно узнать из документации Обычно после стрелки указывают возвращаемое значение. Посудив логически, можно предположить, что данная функция обрабатывает 2 каких-то типа. То есть int и list или str и list. Либо же просто сравнивает 2 числа или 2 строки. И возвращает наибольшее значение из переданных данных. Но это не точно. То есть в общем виде функция может выглядеть примерно так: def function(a, b): if type(b) == list: lst = b[:] # или b.copy() lst.append(a) try: return max(lst) except ValueError: return "'>' not supported between instances of 'int' and 'str'" else: try: return max(a, b) except ValueError: return "'>' not supported between instances of 'int' and 'str'" То есть если мы передадим, например, число 5 и список из чисел [3, 7, 1, 0, 4, 2, -1, 8, -4], то функция вернёт нам наибольшее значение из переданных данных, то есть 8. При вызове, например, этой функции с числом 20 и этим же списком, на выходе мы получим число 20, так как оно больше, чем какое-либо из списка. Что конкретно всё же имелось ввиду в данном случае - не очень понятно. Такой тип написания документации к функции очень плох, ибо не раскрывает цели функции, а также не сообщает что и при каких условиях функция возвращает. Подробнее о документировании классов и функций можно узнать, перейдя по этой ссылке.

понедельник, 28 января 2019 г.

Зачем нужен вызов “-> max(a,b)” при создании функции?

Нашёл такой пример: def function(a:int,b:str,c:list) -> max(2,3):. Зачем используется -> max(...)?


Ответ

В данной строке
def function(a:int,b:str,c:list) -> max(2,3):
:int, :str, :list, -> max(2,3) - это аннотации. Впервые они предлагаются к введению в Python в PEP 3107, но их назначение четко не регламентировалось (их интерпретация возлагалась на авторов сторонних инструментов).
В качестве аннотации может использоваться любое синтаксически верное выражение Python. При запуске кода интерпретатором выражения, используемые в качестве аннотации, исполняются (поэтому могут вызывать ошибки во время исполнения, например выражение def f() -> max(None, 1): pass вызовет ошибку TypeError, пример от jfs), но никаким специальным образом интерпретатором не обрабатываются (т.е., например, интерпретатор сам не проверяет типы).
Позже было более четко зафиксировано использование аннотаций как аннотаций типов (PEP 484), т.е. после аргументов функции через двоеточие пишем предполагаемый тип аргумента, после -> пишем тип возвращаемого значения функции.
Опять же, интерпретатор их игнорирует, но аннотации типов могут использоваться такими инструментами как mypy или встроенным в PyCharm статическим анализатором кода, чтобы понимать, что в функцию передано (или возвращено) значение не того типа, которое предполагалось, и отображать это как ошибку или предупреждение.
-> max(2,3) с моей точки зрения не несет никакой смысловой нагрузки. Это не аннотация типа, а просто аннотация. Что имел в виду автор примера - загадка. Скорее всего это просто пример использования аннотаций.
Программно получить доступ к аннотациям функции можно через атрибут функции __annotations__
def function(a:int,b:str,c:list) -> max(2,3): pass
print(function.__annotations__)
Результат:
{'a': , 'return': 3, 'c': , 'b': }
Здесь видны прописанные для аргументов типы, и видно, что выражение max(2,3) вычислилось, поэтому в качестве аннотации для возвращаемого значения записалось просто 3.