IT story

reduce ()를 사용하는 유용한 코드?

hot-time 2020. 7. 14. 08:01
반응형

reduce ()를 사용하는 유용한 코드? [닫은]


여기에 파이썬에서 reduce () 함수를 사용하는 유용한 코드가 있습니까? 예제에서 볼 수있는 일반적인 + 및 * 이외의 코드가 있습니까?

GvR의 Python 3000에서 Fate of reduce () 참조


내가 + 외에 그것을 발견하고 * 한 다른 용도와와와 나 있었지만, 지금 우리가 가지고 anyall그 사례를 대체 할 수 있습니다.

foldl그리고 foldrScheme에 많이 나옵니다 ...

다음은 귀여운 사용법입니다.

목록을 평평하게

목표 :로 [[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]바꿉니다 12345678.

못생긴, 천천히 :

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)

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

reduce()점으로 구분 된 이름을 확인하는 데 사용할 수 있습니다 (사용하기 eval()에 너무 안전하지 않은 위치 ).

>>> import __main__
>>> reduce(getattr, "os.path.abspath".split('.'), __main__)
<function abspath at 0x009AB530>

주어진 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])

via : Python-두리스트의 교차


감소는 어리석은 명령이라고 생각합니다. 그 후:

reduce(lambda hold,next:hold+chr(((ord(next.upper())-65)+13)%26+65),'znlorabggbbhfrshy','')

reduce내 코드에서 찾은 사용법은 논리 표현식에 대한 클래스 구조가있는 상황과 관련이 있었고 이러한 표현식 객체 목록을 표현식의 조합으로 변환해야했습니다. 나는 이미 make_and두 개의 표현식이 주어진 연결을 만드는 기능 가지고 있었기 때문에 썼다 reduce(make_and,l). (목록이 비어 있지 않다는 것을 알았습니다. 그렇지 않으면 목록과 같았을 것 reduce(make_and,l,make_true)입니다.)

이것이 바로 (일부) 기능 프로그래머가 reduce(또는 그러한 기능이 일반적으로 호출되는 것처럼 접는 기능 ) 프로그래머의 이유입니다 . 이 같은 이미 많은 바이너리 기능 종종 +, *, min, max, 연결은하고, 내 경우에는, make_and하고 make_or. 를 갖는 것은 reduce사소한 (당신이 일반적으로 배 기능, 가지고 어떤 또는 나무 또는) 목록에 이러한 작업을 들어 올릴 수 있습니다.

물론 특정 인스턴스화 (예 :) sum가 자주 사용되는 경우 계속 쓰기를 원하지 않습니다 reduce. 그러나 대신 정의의 sum일부 루프와 함께, 당신은 할 수 있습니다 그냥 간단하게 그것을 정의한다 reduce.

다른 사람들이 언급했듯이 가독성은 실제로 문제입니다. 그러나 사람들 reduce이 "명확하지 않은" 이유를 찾는 이유 는 많은 사람들이 알고 사용하는 기능이 아니기 때문 이라고 주장 할 수 있습니다.


다음 value = json_obj['a']['b']['c']['d']['e']과 같이 바꿀 수 있습니다.

value = reduce(dict.__getitem__, 'abcde', json_obj)

이미 경로 a/b/c/..를 목록으로 가지고 있다면 . 예를 들어, 목록의 항목을 사용하여 중첩 된 dict의 dict 값을 변경하십시오 .


기능 구성 : 다음과 같이 연속으로 적용하려는 기능 목록이 이미있는 경우 :

color = lambda x: x.replace('brown', 'blue')
speed = lambda x: x.replace('quick', 'slow')
work = lambda x: x.replace('lazy', 'industrious')
fs = [str.lower, color, speed, work, str.title]

그런 다음 다음을 사용하여 모두 연속적으로 적용 할 수 있습니다.

>>> call = lambda s, func: func(s)
>>> s = "The Quick Brown Fox Jumps Over the Lazy Dog"
>>> reduce(call, fs, s)
'The Slow Blue Fox Jumps Over The Industrious Dog'

이 경우, 메소드 체인이 더 읽기 쉽습니다. 그러나 때로는 가능하지 않으며 이러한 종류의 구성은 f1(f2(f3(f4(x))))일종의 구문 보다 읽기 쉽고 유지 관리가 쉬울 수 있습니다 .


@Blair Conrad : 다음과 같이 sum을 사용하여 glob / reduce를 구현할 수도 있습니다.

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

이것은 두 예제 중 하나보다 덜 장황하고 완벽하게 Pythonic이며 여전히 한 줄의 코드입니다.

따라서 원래 질문에 대답하기 위해 개인적으로 Reduce는 실제로 필요하지 않으며 다른 접근법보다 덜 명확하다는 것을 알기 때문에 개인적으로 사용하지 마십시오. 그러나 일부 사람들은 이해력을 줄이고 (특히 하스켈 프로그래머들) 그것을 선호하기를 선호합니다. 그러나 축소 측면에서 문제에 대해 아직 생각하고 있지 않다면 사용에 대해 걱정할 필요가 없습니다.


reduce 체인 속성 조회를 지원하는 데 사용할 수 있습니다.

reduce(getattr, ('request', 'user', 'email'), self)

물론 이것은

self.request.user.email

그러나 코드가 임의의 속성 목록을 수락해야 할 때 유용합니다.

(Django 모델을 다룰 때 임의 길이의 체인 속성이 일반적입니다.)


reduceset유사한 객체 시퀀스의 합집합 또는 교차점을 찾아야 할 때 유용 합니다.

>>> reduce(operator.or_, ({1}, {1, 2}, {1, 3}))  # union
{1, 2, 3}
>>> reduce(operator.and_, ({1}, {1, 2}, {1, 3}))  # intersection
{1}

(실제 sets를 제외하고 Django의 Q 객체 입니다.)

반면에 bools를 다루는 경우 anyand 를 사용해야합니다 all.

>>> any((True, False, True))
True

내 코드를 파악한 후 축소에 사용한 유일한 것은 계승을 계산하는 것 같습니다.

reduce(operator.mul, xrange(1, x+1) or (1,))

언어에 대한 작성 기능을 작성하고 있으므로 apply 연산자와 함께 reduce를 사용하여 작성된 기능을 구성합니다.

간단히 말해서 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)))

reduce는 최대 n 번째 요소로 목록을 가져 오는 데 사용할 수 있습니다.

reduce(lambda x,y: x if x[2] > y[2] else y,[[1,2,3,4],[5,2,5,7],[1,6,0,2]])

최대 3 번째 요소가 + 인 목록이므로 [5, 2, 5, 7]을 반환합니다.


Reduce는 스칼라 연산으로 제한되지 않습니다. 버킷으로 항목을 정렬하는 데 사용할 수도 있습니다. (이것이 내가 가장 자주 사용하는 것입니다).

객체 목록이 있고 객체에 평평하게 저장된 속성을 기반으로 계층 적으로 재구성하려는 경우를 상상해보십시오. 다음 예에서는 XML 인코딩 신문의 기사와 관련된 메타 데이터 개체 목록을 articles함수로 생성합니다. articlesXML 요소의 목록을 생성 한 다음이를 통해 하나씩 매핑하여 흥미로운 정보를 보유한 객체를 생성합니다. 프런트 엔드에서 사용자가 섹션 / 하위 섹션 / 제목으로 기사를 찾아 보도록하겠습니다. 따라서 reduce기사 목록을 가져 와서 섹션 / 하위 섹션 / 기사 계층 구조를 반영하는 단일 사전을 반환합니다.

from lxml import etree
from Reader import Reader

class IssueReader(Reader):
    def articles(self):
        arts = self.q('//div3')  # inherited ... runs an xpath query against the issue
        subsection = etree.XPath('./ancestor::div2/@type')
        section = etree.XPath('./ancestor::div1/@type')
        header_text = etree.XPath('./head//text()')
        return map(lambda art: {
            'text_id': self.id,
            'path': self.getpath(art)[0],
            'subsection': (subsection(art)[0] or '[none]'),
            'section': (section(art)[0] or '[none]'),
            'headline': (''.join(header_text(art)) or '[none]')
        }, arts)

    def by_section(self):
        arts = self.articles()

        def extract(acc, art):  # acc for accumulator
            section = acc.get(art['section'], False)
            if section:
                subsection = acc.get(art['subsection'], False)
                if subsection:
                    subsection.append(art)
                else:
                    section[art['subsection']] = [art]
            else:
                acc[art['section']] = {art['subsection']: [art]}
            return acc

        return reduce(extract, arts, {})

객체를 다룰 때 map과 reduce가 서로를 잘 보완하는 방법을 보여주기 때문에 두 기능을 모두 제공합니다. for 루프를 사용하여 동일한 작업을 수행 할 수 있었지만 기능적인 언어로 심각한 시간을 보내면 맵과 축소 측면에서 생각하게되었습니다.

그건 그렇고, 내가하고있는 것처럼 속성을 설정하는 더 좋은 방법이있는 사람이 있다면 설정 extract하려는 속성의 부모가 아직 없을 수도 있습니다.


이것이 당신이 무엇인지 확실하지 않지만 Google에서 소스 코드를 검색 할 수 있습니다 .

Google 코드 검색 에서 'function : reduce () lang : python'대한 링크를 클릭하십시오

언뜻보기에 다음 프로젝트 사용 reduce()

  • 모인
  • 조프
  • 숫자
  • ScientificPython

등등. 그러나 그들은 거대한 프로젝트이기 때문에 놀랍지 않습니다.

감소의 기능은 Guido가 더 명확하다고 생각한 함수 재귀를 사용하여 수행 할 수 있습니다.

최신 정보:

Google의 코드 검색이 2012 년 1 월 15 일에 중단되어 일반 Google 검색으로 되 돌리는 것 외에도 코드 스 니펫 컬렉션 이라는 것이 유망 해 보입니다. 이 (닫힌) 질문에 대한 답변에 다른 많은 자료가 언급되어 있습니다 . .

업데이트 2 (2017 년 5 월 29 일) :

Python 예제 (오픈 소스 코드)의 좋은 소스는 Nullege 검색 엔진 입니다.


import os

files = [
    # full filenames
    "var/log/apache/errors.log",
    "home/kane/images/avatars/crusader.png",
    "home/jane/documents/diary.txt",
    "home/kane/images/selfie.jpg",
    "var/log/abc.txt",
    "home/kane/.vimrc",
    "home/kane/images/avatars/paladin.png",
]

# unfolding of plain filiname list to file-tree
fs_tree = ({}, # dict of folders
           []) # list of files
for full_name in files:
    path, fn = os.path.split(full_name)
    reduce(
        # this fucction walks deep into path
        # and creates placeholders for subfolders
        lambda d, k: d[0].setdefault(k,         # walk deep
                                     ({}, [])), # or create subfolder storage
        path.split(os.path.sep),
        fs_tree
    )[1].append(fn)

print fs_tree
#({'home': (
#    {'jane': (
#        {'documents': (
#           {},
#           ['diary.txt']
#        )},
#        []
#    ),
#    'kane': (
#       {'images': (
#          {'avatars': (
#             {},
#             ['crusader.png',
#             'paladin.png']
#          )},
#          ['selfie.jpg']
#       )},
#       ['.vimrc']
#    )},
#    []
#  ),
#  'var': (
#     {'log': (
#         {'apache': (
#            {},
#            ['errors.log']
#         )},
#         ['abc.txt']
#     )},
#     [])
#},
#[])

def dump(fname,iterable):
  with open(fname,'w') as f:
    reduce(lambda x, y: f.write(unicode(y,'utf-8')), iterable)

sqlalchemy-searchable 연산자 reduce PostgreSQL 검색 벡터 목록을 연결하는 데 사용 했습니다|| .

vectors = (self.column_vector(getattr(self.table.c, column_name))
           for column_name in self.indexed_columns)
concatenated = reduce(lambda x, y: x.op('||')(y), vectors)
compiled = concatenated.compile(self.conn)

I have an old Python implementation of pipegrep that uses reduce and the glob module to build a list of files to process:

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

I found it handy at the time, but it's really not necessary, as something similar is just as good, and probably more readable

files = []
for f in args:
    files.extend(glob.glob(f))

Let say that there are some yearly statistic data stored a list of Counters. We want to find the MIN/MAX values in each month across the different years. For example, for January it would be 10. And for February it would be 15. We need to store the results in a new Counter.

from collections import Counter

stat2011 = Counter({"January": 12, "February": 20, "March": 50, "April": 70, "May": 15,
           "June": 35, "July": 30, "August": 15, "September": 20, "October": 60,
           "November": 13, "December": 50})

stat2012 = Counter({"January": 36, "February": 15, "March": 50, "April": 10, "May": 90,
           "June": 25, "July": 35, "August": 15, "September": 20, "October": 30,
           "November": 10, "December": 25})

stat2013 = Counter({"January": 10, "February": 60, "March": 90, "April": 10, "May": 80,
           "June": 50, "July": 30, "August": 15, "September": 20, "October": 75,
           "November": 60, "December": 15})

stat_list = [stat2011, stat2012, stat2013]

print reduce(lambda x, y: x & y, stat_list)     # MIN
print reduce(lambda x, y: x | y, stat_list)     # MAX

I have objects representing some kind of overlapping intervals (genomic exons), and redefined their intersection using __and__:

class Exon:
    def __init__(self):
        ...
    def __and__(self,other):
        ...
        length = self.length + other.length  # (e.g.)
        return self.__class__(...length,...)

Then when I have a collection of them (for instance, in the same gene), I use

intersection = reduce(lambda x,y: x&y, exons)

I just found useful usage of reduce: splitting string without removing the delimiter. The code is entirely from Programatically Speaking blog. Here's the code:

reduce(lambda acc, elem: acc[:-1] + [acc[-1] + elem] if elem == "\n" else acc + [elem], re.split("(\n)", "a\nb\nc\n"), [])

Here's the result:

['a\n', 'b\n', 'c\n', '']

Note that it handles edge cases that popular answer in SO doesn't. For more in-depth explanation, I am redirecting you to original blog post.


Using reduce() to find out if a list of dates are consecutive:

from datetime import date, timedelta


def checked(d1, d2):
    """
    We assume the date list is sorted.
    If d2 & d1 are different by 1, everything up to d2 is consecutive, so d2
    can advance to the next reduction.
    If d2 & d1 are not different by 1, returning d1 - 1 for the next reduction
    will guarantee the result produced by reduce() to be something other than
    the last date in the sorted date list.

    Definition 1: 1/1/14, 1/2/14, 1/2/14, 1/3/14 is consider consecutive
    Definition 2: 1/1/14, 1/2/14, 1/2/14, 1/3/14 is consider not consecutive

    """
    #if (d2 - d1).days == 1 or (d2 - d1).days == 0:  # for Definition 1
    if (d2 - d1).days == 1:                          # for Definition 2
        return d2
    else:
        return d1 + timedelta(days=-1)

# datelist = [date(2014, 1, 1), date(2014, 1, 3),
#             date(2013, 12, 31), date(2013, 12, 30)]

# datelist = [date(2014, 2, 19), date(2014, 2, 19), date(2014, 2, 20),
#             date(2014, 2, 21), date(2014, 2, 22)]

datelist = [date(2014, 2, 19), date(2014, 2, 21),
            date(2014, 2, 22), date(2014, 2, 20)]

datelist.sort()

if datelist[-1] == reduce(checked, datelist):
    print "dates are consecutive"
else:
    print "dates are not consecutive"

참고URL : https://stackoverflow.com/questions/15995/useful-code-which-uses-reduce

반응형