azaltmak kullanan Yararlı kodu ()?

oy
113

Burada herkes python () fonksiyonunu azaltmak kullanan herhangi bir yararlı kod var mı? herhangi bir kod olağan + dışındaki var mı ve biz örneklerde gördüğümüz *?

Bkz Python 3000) (azaltmak Akıbetinin GvR tarafından

Oluştur 19/08/2008 saat 10:16
kaynak kullanıcı
Diğer dillerde...                            


24 cevaplar

oy
3

Bu peşindesiniz ama ne olup olmadığından emin değil Google'da kaynak kodlarında arama .

Bir arama için bağlantıyı takip 'işlevi: (azaltmak) lang: piton' Google Code aramada

İlk bakışta aşağıdaki projeler kullanın reduce()

  • MoinMoin
  • Zope
  • Sayısal
  • scientificpython

vs vs ama sonra bu onlar büyük projelerdir beri pek şaşırtıcı bulunmaktadır.

azaltmak işlevselliği ben Guido daha açık olduğunu düşündüm sanırım fonksiyon özyineleme kullanarak yapılabilir.

Güncelleştirme:

Google'ın Code Search 15-Jan-2012 durdurulan bu yana, normal Google aramaları geri dönerek yanında diye birşey var Kod Parçaları Koleksiyon umut verici görünüyor. Diğer kaynaklar bir dizi cevapları bu (kapalı) soru bahsedilmektedir Google Code Search için Değiştirilmesi? .

2 (29-Mayıs-2017) güncelleyin:

(Açık kaynak kodunda) Python örnekler için iyi bir kaynaktır Nullege arama motoru .

Cevap 19/08/2008 saat 11:16
kaynak kullanıcı

oy
1

Ben eski bir Python uygulaması var pipegrep azaltmak kullanır ve sürece dosyaların bir listesini oluşturmak için glob modülü:

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

Ben o zaman kullanışlı buldum, ama benzer bir şey muhtemelen daha okunabilir gibi iyi ve gibi, gerçekten gerekli değil

files = []
for f in args:
    files.extend(glob.glob(f))
Cevap 19/08/2008 saat 11:43
kaynak kullanıcı

oy
7

@Blair Conrad: Ayrıca şöyle, toplamı kullanarak azaltmak / senin topak uygulamak:

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

Bu, sizin iki örneklerden birine göre daha az ayrıntılı mükemmel Pythonictir ve hala kod sadece bir çizgidir.

Yani orijinal soruyu cevaplamak için, ben şahsen gerçekten gerekli asla çünkü azaltmak kullanmaktan kaçınması ve bunu diğer yaklaşımlara göre daha az net olarak görüyorum. Ancak, bazı insanlar azaltmak ve comprehensions (özellikle Haskell programcılar) listelemek için tercih gelmek alışmak. Zaten azaltmak açısından bir sorun düşünmeye değilseniz Ama, muhtemelen kullanırken konusunda endişelenmenize gerek yoktur.

Cevap 19/08/2008 saat 12:57
kaynak kullanıcı

oy
3

kodumu grepping sonra, ben çarpınımını hesaplıyor için azaltmak kullandım tek şey görünüyor:

reduce(operator.mul, xrange(1, x+1) or (1,))
Cevap 21/08/2008 saat 20:40
kaynak kullanıcı

oy
11

Kullanımı reducebenim kodunda bulduğu ben mantık ifadesi için bazı sınıf yapıya sahipti durumu dahil ve ifadelerin bir arada bu ifade nesnelerin listesini dönüştürmek için gerekli. Zaten bir işlevi vardı make_andiki ifadeler verilen bir bağlaç yaratmak için, bu yüzden yazdım reduce(make_and,l). (; Gibi aksi takdirde olurdu şey ben listesi boş olmadığını biliyordum reduce(make_and,l,make_true).)

Bu, tam olarak (bazı) işlevsel gibi programcılar nedenidir reduce(ya da kat bu fonksiyonları genellikle denir olarak, fonksiyonlar). Orada gibi zaten birçok ikili fonksiyonlar genellikle +, *, min, maxbirleştirmek ve benim durumumda, make_andve make_or. Bir Having reduceÖnemsiz (genel olarak kat fonksiyonlar için, elinizde ne varsa veya ağaçların ya) listelerine bu işlemleri kaldırmaya kılar.

(Örneğin belirli örneklemi Tabii ki, eğer sum) sıklıkla kullanılır, o zaman yazmaya devam etmek istemiyoruz reduce. Ancak, bunun yerine tanımlanması sumbazıları için-döngü ile, sen yapabilirsiniz aynı kolaylıkla ile tanımlamak reduce.

Başkaları tarafından belirtildiği gibi Okunabilirlik, aslında bir konudur. İnsanların bulmak tek nedeni Ancak, iddia olabilir reduceo birçok kişi ve / veya kullanımını bilmek bir işlev değil, çünkü daha az "açık" tır.

Cevap 03/09/2008 saat 12:27
kaynak kullanıcı

oy
63

Ben + yanında bunun için bulundu ve * ettik diğer kullanımları ile ve ve ya vardı, ama şimdi var anyve allbu davaları yerine.

foldlve foldrŞemada bir sürü geliyor ...

İşte bazı sevimli kullanımları var:

bir liste düzleştiriniz

Hedef: çevirmek [[1, 2, 3], [4, 5], [6, 7, 8]]içine [1, 2, 3, 4, 5, 6, 7, 8].

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

bir sayıya basamak listesi

Hedef: çevirmek [1, 2, 3, 4, 5, 6, 7, 8]içine 12345678.

Çirkin, Uzun yol:

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

Oldukça reduceyol:

reduce(lambda a,d: 10*a+d, [1,2,3,4,5,6,7,8], 0)
Cevap 11/11/2008 saat 06:29
kaynak kullanıcı

oy
47

reduce()bulmak için kullanılabilecek 3 veya daha fazla sayılar için Az ortak katı :

#!/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)

Örnek:

>>> lcm(100, 23, 98)
112700
>>> lcm(*range(1, 20))
232792560
Cevap 11/11/2008 saat 20:33
kaynak kullanıcı

oy
35

reduce()noktalı isimler (burada çözmek için kullanılabilecek eval()kullanmak için çok güvensiz):

>>> import __main__
>>> reduce(getattr, "os.path.abspath".split('.'), __main__)
<function abspath at 0x009AB530>
Cevap 12/11/2008 saat 00:02
kaynak kullanıcı

oy
3

Bir dil için bir oluşturma işlevi yazıyorum, bu yüzden uygulamak operatör ile birlikte azaltmak kullanarak oluşan fonksiyonu inşa.

Özetle, oluşturmak tek fonksiyonu içine oluşturmak için işlevlerin bir listesini alır. Ben aşamalarında uygulanan bir kompleks işlemi varsa, ben şöyle Hepsini bir araya koymak istiyorum:

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

Bu şekilde, o zaman şöyle bir ifadesi uygulayabilirsiniz:

complexop(expression)

Ve bunun eşdeğer olmasını istiyorum:

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

Şimdi, bunu söylemek istiyorum, benim iç nesneleri oluşturmak için:

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

(Lambda sınıfı, bir kullanıcı tanımlı bir işlev oluşturur ve uygulama fonksiyonu uygulaması oluşturur.)

Şimdi, azaltmak maalesef yanlış bir şekilde kıvrımlar, bu yüzden kabaca kullanarak tasfiye:

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

üretir azaltmak, repl bu deneyin ne olduğunu anlamaya için:

reduce(lambda x, y: (x, y), range(1, 11))
reduce(lambda x, y: (y, x), reversed(range(1, 11)))
Cevap 23/04/2010 saat 19:34
kaynak kullanıcı

oy
20

N verilen listelerin kavşak bulun:

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))

döner:

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

via: Python - iki listeleri Kavşak

Cevap 17/07/2010 saat 16:05
kaynak kullanıcı

oy
7

Sen yerini alabilir value = json_obj['a']['b']['c']['d']['e']ile:

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

Zaten yolunu varsa a/b/c/..bir liste olarak. Örneğin, bir listede öğeleri kullanarak iç içe dicts ait dict değerleri değiştirin .

Cevap 19/08/2012 saat 10:15
kaynak kullanıcı

oy
11

Garip bir komuttur azaltmak düşünüyorum. Dolayısıyla:

reduce(lambda hold,next:hold+chr(((ord(next.upper())-65)+13)%26+65),'znlorabggbbhfrshy','')
Cevap 29/08/2012 saat 04:34
kaynak kullanıcı

oy
3

sayıl operasyonlar sınırlı değildir azaltın; o da kova içine şeyleri sıralamak için kullanılabilir. (Bu benim en sık için azaltmak kullanmak budur).

Eğer nesnelerin listesini sahip olduğu bir durumu hayal sen nesnede kesin bir dille saklanan özelliklerine dayanarak hiyerarşik yeniden düzenlemek istiyoruz. Aşağıdaki örnekte, bir XML kodlanmış gazetesinde makalelere ilişkin meta nesnelerin listesini üretmek articlesfonksiyonu. articlesXML öğelerinin bir listesini oluşturur ve sonra onlar hakkında bazı ilginç bilgi tutun nesneleri üreten tek tek içlerinden eşler. Ön ucunda, ben kullanıcı bölümü / alt bölümünde / başlığa göre makaleleri taramak izin vermek istiyorum gidiyorum. Bu yüzden kullanmak reducemakalelerin listesini alıp bölüm / alt bölüm / makale hiyerarşisini yansıtan tek bir sözlük dönmek için.

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, {})

Ben harita ve nesneler ile uğraşırken güzel birbirlerini tamamlayıcı azaltmak gösterir düşünüyorum çünkü ben burada iki işlevi verir. Aynı şey, for döngüsü ile üstesinden gelinebilecek ... ama işlevsel bir dil ile bazı ciddi vakit bana haritada açısından düşünmek ve azaltmak yapmak eğiliminde olmuştur.

Bu arada, herkes ben yapıyorum gibi özellikleri ayarlamak için daha iyi bir yol varsa extracthenüz mevcut olmayabilir ayarlamak istediğiniz mülkün veliler, lütfen bana bildirin.

Cevap 07/09/2012 saat 01:23
kaynak kullanıcı

oy
1

Maksimum n'inci elemanı ile listesini almak için kullanılabilir azaltmak

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

dönmek [5, 2, 5, 7] maksimum 3 eleman ile liste + olduğu gibi

Cevap 21/03/2013 saat 05:06
kaynak kullanıcı

oy
4

Fonksiyon kompozisyon : Zaten gibi Art arda uygulamak istediğiniz fonksiyonları, bir liste varsa:

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]

Sonra birlikte art arda hepsini uygulayabilirsiniz:

>>> 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'

Bu durumda, yöntem, zincirleme daha okunabilir olabilir. Ama bazen bu mümkün değildir ve kompozisyonun bu tür bir daha okunabilir ve sürdürülebilir olabilir f1(f2(f3(f4(x))))sözdizimi tür.

Cevap 15/01/2014 saat 15:55
kaynak kullanıcı

oy
0

tarihlerinin listesi ardışık olup olmadığını öğrenmek için) (azaltmak kullanarak:

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"
Cevap 22/02/2014 saat 13:16
kaynak kullanıcı

oy
1

Sayaçların listesi depolanan bazı yıllık istatistik veri yoktur diyelim. Farklı yıllarda genelinde her ay MIN / MAX değerlerini bulmak istiyoruz. Örneğin, Ocak için 10 olurdu Ve şubat için Biz yeni bir Sayaç sonuçları saklamak gerekir 15. olacaktır.

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
Cevap 22/02/2014 saat 13:18
kaynak kullanıcı

oy
2
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']
#     )},
#     [])
#},
#[])
Cevap 20/05/2014 saat 15:08
kaynak kullanıcı

oy
1

I aralıkları (genomik eksonlar) üst üste binen bir tür temsil nesneleri ve kullanarak kavşak yeniden __and__:

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

Ben (aynı gende, örneğin) onlardan bir koleksiyona sahip Sonra, kullandığım

intersection = reduce(lambda x,y: x&y, exons)
Cevap 05/06/2014 saat 12:40
kaynak kullanıcı

oy
4

reduce zincirleme nitelik aramalarını desteklemek için kullanılabilir:

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

Tabii ki, bu eşdeğerdir

self.request.user.email

Kodunuzu özelliklerin rastgele bir listesini kabul etmesi gerektiğinde ancak yararlıdır.

(Django modelleri ile uğraşırken istenilen uzunlukta Zincirli nitelikler yaygındır.)

Cevap 20/06/2014 saat 06:07
kaynak kullanıcı

oy
3

reduceEğer bir dizinin birliği veya kavşağı bulmak için gerektiğinde yararlıdır setbenzeri nesneler.

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

(Yanı gerçek gelen sets, bu bir örnektir Django'nın S nesneleri .)

Uğraştığın Öte yandan, bools, kullanmak gerekir anyve all:

>>> any((True, False, True))
True
Cevap 20/06/2014 saat 06:37
kaynak kullanıcı

oy
2
def dump(fname,iterable):
  with open(fname,'w') as f:
    reduce(lambda x, y: f.write(unicode(y,'utf-8')), iterable)
Cevap 16/09/2015 saat 13:43
kaynak kullanıcı

oy
1

Sadece yararlı kullanımını bulundu reduce: sınırlayıcı çıkarmadan bölme dize . Kod Programlama yoluyla konuşan blogdan tamamen size aittir. İşte kod:

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

İşte sonuç var:

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

o SO popüler cevap değil yaptığı kenar davalarına bakan unutmayın. Daha derinlemesine bir açıklama için orijinal blog yayınına yönlendiriyor ediyorum.

Cevap 24/11/2015 saat 11:31
kaynak kullanıcı

oy
2

Ben kullanılan reduce PostgreSQL arama vektörlerin bir listesini bitiştirmek ile ||sqlalchemy aranabilir operatör:

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)
Cevap 06/01/2016 saat 02:10
kaynak kullanıcı

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more