Полезный код, который использование уменьшает ()? [закрытый]

Пожалуйста, не принимайте это как ответ на вопрос. Это не так, но совет, связанный с использованием разности int и float. Я бы поставил это под комментарием, за исключением того, что поле ответа позволяет мне форматировать этот комментарий.

Эта функция использовалась на каждом уважаемом языке программирования со времен fortran (или раньше) - я должен признаться Я когда-то был программистом перформанса Fortran и Cobol.

В качестве примера, целочисленное деление 10/3 дает целочисленное значение 3, поскольку целое число не имеет возможности удерживать дробное остаточное число .3333 ...

Один из способов, которыми мы (старые программисты) использовали эту функцию, - это управление контуром.

Предположим, мы хотим напечатать массив из 1000 строк, но мы хотим вставить строку перерыв после каждой 15-й строки, чтобы вставить некоторые симпатичные символы в конце строки и в начале следующей строки. Мы используем это, учитывая, что целое число k является позицией строки в этом массиве.

int(k/15)*15 == k

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

int(1/15) = 0 -> int(1/15)*15 = 0
int(2/15) = 0 -> int(2/15)*15 = 0
...
int(14/15) = 0 -> int(14/15)*15 = 0
int(15/15) = 1 -> int(15/15)*15 = 15

int(16/15) = 1 -> int(16/15)*15 = 15
int(17/15) = 1 -> int(17/15)*15 = 15
...
int(29/15) = 1 -> int(29/15)*15 = 15
int(30/15) = 2 -> int(30/15)*15 = 30

Поэтому цикл

leftPrettyfy();
for(int k=0; k<sa.length; k++){
  print(sa[k]);
  int z = k + 1;
  if ((z/15)*15 == z){
    rightPrettyfy();
    leftPrettyfy();
  }
}

Изменяя k в причудливом в цикле, мы могли бы напечатать треугольную распечатку

1
2  3
4  5  6
7  8  9  10
11 12 13 14 15

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

120
задан martineau 30 May 2017 в 04:07
поделиться

10 ответов

Не уверенный, если это - то, что Вы после, но Вы можете , поисковый исходный код на Google .

Переходит по ссылке для поиска на 'function:reduce () lang:python' на Поиске кода Google

На первый взгляд следующее использование проектов reduce()

  • MoinMoin
  • Zope
  • , Числовой
  • ScientificPython

и т.д. и т.д., но затем они едва удивительны, так как они - огромные проекты.

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

Обновление:

Поиск кода Google Since был прекращен 15 января 2012 помимо возвращения к регулярным поискам Google, существует что-то позвонившее Набор Фрагментов кода , который выглядит многообещающим. Много других ресурсов упоминаются в ответах этот (закрытый) вопрос Замена для Google Code Search? .

Обновление 2 (29 мая 2017):

А хороший источник для примеров Python (в открытом исходном коде) Nullege  search  механизм .

3
ответ дан 24 November 2019 в 01:37
поделиться

У меня есть старая реализация Python pipegrep, который использование уменьшает и модуль шарика для создания списка файлов для обработки:

files = []
files.extend(reduce(lambda x, y: x + y, map(glob.glob, args)))

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

files = []
for f in args:
    files.extend(glob.glob(f))
1
ответ дан 24 November 2019 в 01:37
поделиться

Другое использование, которое я нашел для него, кроме того, + и *, было с и и или, но теперь мы имеем any и all для замены тех случаев.

foldl и foldr действительно подходят в Схеме много...

Вот некоторые милые использования:

Сглаживают список

Цель: поворот [[1, 2, 3], [4, 5], [6, 7, 8]] в [1, 2, 3, 4, 5, 6, 7, 8].

reduce(list.__add__, [[1, 2, 3], [4, 5], [6, 7, 8]], [])

Список цифр к Цели номер

: поворот [1, 2, 3, 4, 5, 6, 7, 8] в [1 110].

Ужасный, медленный путь:

int("".join(map(str, [1,2,3,4,5,6,7,8])))

Симпатичный reduce путь:

reduce(lambda a,d: 10*a+d, [1,2,3,4,5,6,7,8], 0)
64
ответ дан 24 November 2019 в 01:37
поделиться

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

reduce(operator.mul, xrange(1, x+1) or (1,))
3
ответ дан 24 November 2019 в 01:37
поделиться

@Blair Conrad: Вы могли также реализовать свой шарик/уменьшать с помощью суммы, как так:

files = sum([glob.glob(f) for f in args], [])

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

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

7
ответ дан 24 November 2019 в 01:37
поделиться

Использование reduce, что я нашел в своем коде, включило ситуацию, где у меня была некоторая структура класса для логического выражения, и я должен был преобразовать список этих, выражение возражает против соединения выражений. У меня уже была функция make_and для создания соединения, учитывая два выражения, таким образом, я записал reduce(make_and,l). (Я знал, что список не был пуст; иначе это было бы что-то как reduce(make_and,l,make_true).)

Это - точно причина, что (немного) функциональные программисты как reduce (или сгиб функции, функции как таковые обычно вызываются). Часто уже существует много двоичных функций как +, *, min, max, конкатенация и, в моем случае, make_and и make_or. Наличие reduce делает это тривиальным для подъема этих операций к спискам (или деревья или независимо от того, что Вы добрались для функций сгиба в целом).

, Конечно, если определенные инстанцирования (такой как [1 112]) часто используются, то Вы не хотите продолжать писать reduce. Однако вместо того, чтобы определить sum с некоторыми для цикла, Вы можете столь же легко определять его с [1 115].

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

11
ответ дан 24 November 2019 в 01:37
поделиться

reduce() мог использоваться для разрешения отмеченных точкой имен (где eval() слишком небезопасно для использования):

>>> import __main__
>>> reduce(getattr, "os.path.abspath".split('.'), __main__)
<function abspath at 0x009AB530>
38
ответ дан 24 November 2019 в 01:37
поделиться

reduce() может использоваться для нахождения Наименьшее общее кратное для 3 или больше чисел :

#!/usr/bin/env python
from fractions import gcd
from functools import reduce

def lcm(*args):
    return reduce(lambda a,b: a * b // gcd(a, b), args)

Пример:

>>> lcm(100, 23, 98)
112700
>>> lcm(*range(1, 20))
232792560
50
ответ дан 24 November 2019 в 01:37
поделиться

Я пишу функцию compose для языка, поэтому я создаю составную функцию, используя reduce вместе с моим оператором apply.

Вкратце, compose принимает список функций, которые нужно объединить в одну функцию. Если у меня есть сложная операция, которая выполняется поэтапно, я хочу собрать все это вместе следующим образом:

complexop = compose(stage4, stage3, stage2, stage1)

Таким образом, я могу применить ее к выражению, подобному такому:

complexop(expression)

И я хочу, чтобы это было эквивалентно :

stage4(stage3(stage2(stage1(expression))))

Теперь, чтобы построить мои внутренние объекты, я хочу, чтобы он сказал:

Lambda([Symbol('x')], Apply(stage4, Apply(stage3, Apply(stage2, Apply(stage1, Symbol('x'))))))

(Класс Lambda создает определяемую пользователем функцию, а Apply создает приложение функции.)

Теперь, к сожалению, уменьшить свертки неправильно, поэтому я закончил примерно так:

reduce(lambda x,y: Apply(y, x), reversed(args + [Symbol('x')]))

Чтобы выяснить, что дает сокращение, попробуйте в REPL:

reduce(lambda x, y: (x, y), range(1, 11))
reduce(lambda x, y: (y, x), reversed(range(1, 11)))
3
ответ дан 24 November 2019 в 01:37
поделиться

Найдите пересечение N заданных списков:

input_list = [[1, 2, 3, 4, 5], [2, 3, 4, 5, 6], [3, 4, 5, 6, 7]]

result = reduce(set.intersection, map(set, input_list))

возвращает:

result = set([3, 4, 5])

через: Python - пересечение двух списков

23
ответ дан 24 November 2019 в 01:37
поделиться
Другие вопросы по тегам:

Похожие вопросы: