क्या यहां किसी के पास कोई उपयोगी कोड है जो अजगर में कम () फ़ंक्शन का उपयोग करता है? क्या सामान्य और + के अलावा कोई ऐसा कोड है जिसे हम उदाहरणों में देखते हैं?
जीवीआर द्वारा पायथन 3000 में कम () की किस्मत देखें
क्या यहां किसी के पास कोई उपयोगी कोड है जो अजगर में कम () फ़ंक्शन का उपयोग करता है? क्या सामान्य और + के अलावा कोई ऐसा कोड है जिसे हम उदाहरणों में देखते हैं?
जीवीआर द्वारा पायथन 3000 में कम () की किस्मत देखें
जवाबों:
इसके अलावा और इसके लिए मैंने जो अन्य उपयोग किए हैं, वे + और * के साथ और या थे, लेकिन अब हमारे पास any
और all
उन मामलों को बदलने के लिए हैं।
foldl
और foldr
स्कीम में आगे आओ ...
यहाँ कुछ प्यारा usages है:
एक सूची को समतल करें
लक्ष्य: बारी [[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)
timeit.repeat('int("".join(map(str, digit_list)))', setup = 'digit_list = list(d%10 for d in xrange(1,1000))', number=1000)
जबकि timeit.repeat('reduce(lambda a,d: 10*a+d, digit_list)', setup = 'digit_list = list(d%10 for d in xrange(1,1000))', number=1000)
0.36 सेकंड (लगभग 4 गुना धीमा) लेता है। मूल रूप से सूची बड़ी हो जाने पर मूल रूप से गुणन 10 गुना महंगा हो जाता है, जबकि इंट टू स्ट्रट एंड कॉन्टेनेशन सस्ता रहता है।
timeit.repeat('convert_digit_list_to_int(digit_list)', setup = 'digit_list = [d%10 for d in xrange(1,10)]\ndef convert_digit_list_to_int(digits):\n i = 0\n for d in digits:\n i = 10*i + d\n return i', number=100000)
होता है, 0.06 s timeit.repeat('reduce(lambda a,d: 10*a+d, digit_list)', setup = 'digit_list = list(d%10 for d in xrange(1,10))', number=100000)
लेता है , 0.12 s लेता है और अंको को str विधि में परिवर्तित करने में 0.16 s लेता है।
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
lcm
दूसरी पंक्ति में क्या है ?
एन दी गई सूचियों के प्रतिच्छेदन का पता लगाएं:
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])
के माध्यम से: पायथन - दो सूचियों का अंतर्ग्रहण
मुझे लगता है कि कम करना एक मूर्खतापूर्ण आदेश है। अत:
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
कम "स्पष्ट" पाते हैं क्योंकि यह एक ऐसा कार्य नहीं है जिसे बहुत से लोग जानते हैं और / या उपयोग करते हैं।
and
L and reduce(make_and, L)
कार्य संरचना : यदि आपके पास पहले से ही ऐसे कार्यों की सूची है, जिन्हें आप उत्तराधिकार में लागू करना चाहते हैं, जैसे:
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))))
प्रकार के वाक्य रचना की तुलना में अधिक पठनीय और बनाए रखने योग्य हो सकती है ।
आप इसके value = json_obj['a']['b']['c']['d']['e']
साथ प्रतिस्थापित कर सकते हैं :
value = reduce(dict.__getitem__, 'abcde', json_obj)
यदि आपके पास पहले से a/b/c/..
सूची के रूप में रास्ता है । उदाहरण के लिए, सूची में आइटमों का उपयोग करते हुए नेस्टेड डिक्ट्स के हुक्म में मान बदलें ।
@ ब्लेयर कॉनराड: आप अपने ग्लोब को लागू कर सकते हैं / राशि का उपयोग कम कर सकते हैं, जैसे:
files = sum([glob.glob(f) for f in args], [])
यह आपके दोनों उदाहरणों की तुलना में कम वर्बोज़ है, बिल्कुल पाइथोनिक है, और अभी भी कोड की केवल एक पंक्ति है।
इसलिए मूल प्रश्न का उत्तर देने के लिए, मैं व्यक्तिगत रूप से कम करने से बचने की कोशिश करता हूं क्योंकि यह वास्तव में आवश्यक नहीं है और मुझे यह अन्य दृष्टिकोणों की तुलना में कम स्पष्ट लगता है। हालांकि, कुछ लोगों को कम करने की आदत हो जाती है और यह पसंद को समझने के लिए आते हैं (विशेषकर हास्केल प्रोग्रामर)। लेकिन अगर आप पहले से ही किसी समस्या को कम करने के बारे में नहीं सोच रहे हैं, तो आपको इसका उपयोग करने के बारे में चिंता करने की आवश्यकता नहीं है।
sum
और reduce
द्विघात व्यवहार को जन्म देते हैं। यह रैखिक समय में किया जा सकता है files = chain.from_iterable(imap(iglob, args))
:। हालाँकि यह संभवतः इस मामले में मायने नहीं रखता है क्योंकि डिस्क तक पहुँचने के लिए ग्लोब () में समय लगता है।
reduce
जंजीर विशेषता लुकअप का समर्थन करने के लिए इस्तेमाल किया जा सकता है:
reduce(getattr, ('request', 'user', 'email'), self)
बेशक, यह इसके बराबर है
self.request.user.email
लेकिन यह तब उपयोगी है जब आपके कोड को विशेषताओं की एक मनमानी सूची को स्वीकार करने की आवश्यकता हो।
(Django मॉडल के साथ काम करते समय मनमानी लंबाई की जंजीर विशेषताएँ आम हैं।)
reduce
उपयोगी है जब आपको समान set
वस्तुओं के अनुक्रम के संघ या चौराहे को खोजने की आवश्यकता होती है ।
>>> reduce(operator.or_, ({1}, {1, 2}, {1, 3})) # union
{1, 2, 3}
>>> reduce(operator.and_, ({1}, {1, 2}, {1, 3})) # intersection
{1}
(वास्तविक set
एस के अलावा , इन का एक उदाहरण Django के क्यू ऑब्जेक्ट हैं ।)
दूसरी ओर, यदि आप bool
एस के साथ काम कर रहे हैं, तो आपको उपयोग करना चाहिए any
और all
:
>>> any((True, False, True))
True
मेरे कोड को टटोलने के बाद, यह केवल एक चीज है जिसके लिए मैंने कम का उपयोग किया है, तथ्य की गणना कर रहा है:
reduce(operator.mul, xrange(1, x+1) or (1,))
मैं एक भाषा के लिए एक रचना फ़ंक्शन लिख रहा हूं, इसलिए मैं अपने लागू ऑपरेटर के साथ कम करने का उपयोग करके रचना की रचना करता हूं।
संक्षेप में, रचना एक एकल फ़ंक्शन में रचना करने के लिए कार्यों की एक सूची लेती है। यदि मेरे पास एक जटिल ऑपरेशन है जिसे चरणों में लागू किया जाता है, तो मैं इसे सभी को एक साथ रखना चाहता हूं:
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'))))))
(लैम्ब्डा वर्ग एक उपयोगकर्ता-परिभाषित फ़ंक्शन बनाता है, और लागू एक फ़ंक्शन एप्लिकेशन बनाता है।)
अब, दुर्भाग्य से, गलत तरीके से कम करें, इसलिए मैं घाव का उपयोग कर रहा हूं, मोटे तौर पर:
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)))
compose = lambda *func: lambda arg: reduce(lambda x, f: f(x), reversed(funcs), arg)
को उत्पन्न
कम करने के लिए अधिकतम nth तत्व के साथ सूची प्राप्त करने के लिए इस्तेमाल किया जा सकता है
reduce(lambda x,y: x if x[2] > y[2] else y,[[1,2,3,4],[5,2,5,7],[1,6,0,2]])
यह [५, २, ५, as] लौटाएगा क्योंकि यह अधिकतम ३ तत्व + के साथ सूची है
कमी स्केलर ऑपरेशन तक सीमित नहीं है; यह भी बाल्टी में चीजों को सॉर्ट करने के लिए इस्तेमाल किया जा सकता है। (यह वह है जो मैं सबसे अधिक बार कम करता हूं)।
एक ऐसे मामले की कल्पना करें जिसमें आपके पास वस्तुओं की एक सूची है, और आप इसे ऑब्जेक्ट में सपाट रूप से संग्रहीत गुणों के आधार पर श्रेणीबद्ध रूप से फिर से व्यवस्थित करना चाहते हैं। निम्नलिखित उदाहरण में, मैं articles
फ़ंक्शन के साथ XML-एन्कोडेड समाचार पत्र में लेखों से संबंधित मेटाडेटा ऑब्जेक्ट्स की एक सूची तैयार करता हूं । articles
XML तत्वों की एक सूची बनाता है, और फिर उनके माध्यम से एक-एक करके उन वस्तुओं का निर्माण करता है जो उनके बारे में कुछ दिलचस्प जानकारी रखते हैं। सामने के छोर पर, मैं उपयोगकर्ता को अनुभाग / उपधारा / शीर्षक द्वारा लेख ब्राउज़ करने देना चाहता हूं। इसलिए मैं 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, {})
मैं यहां दोनों कार्य देता हूं क्योंकि मुझे लगता है कि यह दिखाता है कि वस्तुओं के साथ काम करते समय नक्शा और कमी एक दूसरे के पूरक कैसे हो सकते हैं। एक ही बात को लूप के साथ पूरा किया जा सकता था, ... लेकिन एक कार्यात्मक भाषा के साथ कुछ गंभीर समय बिताना मुझे मानचित्र के संदर्भ में सोचने और कम करने के लिए प्रेरित करता है।
वैसे, अगर किसी के पास संपत्तियों को सेट करने का एक बेहतर तरीका है जैसे मैं कर रहा हूं extract
, जहां आप जिस संपत्ति को सेट करना चाहते हैं, उसके माता-पिता अभी तक मौजूद नहीं हैं, तो कृपया मुझे बताएं।
सुनिश्चित नहीं है कि यह वही है जो आप बाद में हैं लेकिन आप Google पर स्रोत कोड खोज सकते हैं ।
खोज के लिए लिंक का अनुसरण करें 'फ़ंक्शन: कम करें () लैंग: अजगर'Google कोड खोज करें
पहली नज़र में निम्नलिखित परियोजनाएँ उपयोग करती हैं reduce()
वगैरह-वगैरह लेकिन तब ये मुश्किल से हैरान होते हैं क्योंकि ये बहुत बड़े प्रोजेक्ट होते हैं।
कम करने की कार्यक्षमता फ़ंक्शन रिकर्सन का उपयोग करके की जा सकती है जो मुझे लगता है कि गुइडो सोचा अधिक स्पष्ट था।
अपडेट करें:
चूंकि Google की कोड खोज 15-Jan-2012 को बंद कर दी गई थी, इसके अलावा नियमित रूप से Google खोजों को बदलने के अलावा, कोड स्निपेट संग्रह नामक कुछ ऐसा है जो आशाजनक दिखता है। इस (बंद) प्रश्न रिप्लेसमेंट फॉर गूगल कोड सर्च में कई अन्य संसाधनों का उल्लेख किया गया है ? ।
अपडेट 2 (29-मई-2017):
पायथन उदाहरणों के लिए एक अच्छा स्रोत (ओपन-सोर्स कोड में) Nullege सर्च इंजन है ।
for
लूप।
lang:python "reduce("
के reduce
आधार पर खोज करने पर भी परिभाषा मिलेगी ।
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']
# )},
# [])
#},
#[])
मैं sqlalchemy-sear विकल्प में ऑपरेटर के साथ 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)
मेरे पास पाइपग्रेप का एक पुराना पायथन कार्यान्वयन है जो प्रक्रिया को फाइलों की सूची बनाने के लिए कम और ग्लोब मॉड्यूल का उपयोग करता है:
files = []
files.extend(reduce(lambda x, y: x + y, map(glob.glob, args)))
मुझे यह समय पर आसान लगा, लेकिन यह वास्तव में आवश्यक नहीं है, क्योंकि ऐसा ही कुछ अच्छा है, और शायद अधिक पठनीय है
files = []
for f in args:
files.extend(glob.glob(f))
files = [glob.glob(f) for f in args]
itertools
का उपयोग करके , और फिर लिखना: (और इस बार, मैंने इसे पोस्ट करने से पहले कोड का परीक्षण किया, और मुझे पता है कि यह सही ढंग से काम करता है।)flatten()
files = flatten(glob.glob(f) for f in args)
files = chain.from_iterable(imap(iglob, args))
जहां chain
, imap
से हैं itertools
मॉड्यूल और glob.iglob
उपयोगी होती है, से एक पैटर्न args
कई निर्देशिकाओं से फाइल मिल सकता है।
बता दें कि कुछ वार्षिक आंकड़ों में काउंटर्स की एक सूची संग्रहीत है। हम अलग-अलग वर्षों में प्रत्येक महीने में न्यूनतम / अधिकतम मान खोजना चाहते हैं। उदाहरण के लिए, जनवरी के लिए यह 10. होगा और फरवरी के लिए यह 15 होगा। हमें एक नए काउंटर में परिणामों को संग्रहीत करने की आवश्यकता है।
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
मेरे पास कुछ प्रकार के अतिव्यापी अंतराल (जीनोमिक एक्सॉन) का प्रतिनिधित्व करने वाली वस्तुएं हैं, और उनका उपयोग करके अपने चौराहे को फिर से परिभाषित किया है __and__
:
class Exon:
def __init__(self):
...
def __and__(self,other):
...
length = self.length + other.length # (e.g.)
return self.__class__(...length,...)
फिर जब मेरे पास उनका संग्रह होता है (उदाहरण के लिए, उसी जीन में), मैं उपयोग करता हूं
intersection = reduce(lambda x,y: x&y, exons)
मैंने सिर्फ इसका उपयोगी उपयोग पाया reduce
: सीमांकक को हटाए बिना स्ट्रिंग को विभाजित करना । कोड पूरी तरह से प्रोग्राम स्पीकिंग ब्लॉग से है। यहाँ कोड है:
reduce(lambda acc, elem: acc[:-1] + [acc[-1] + elem] if elem == "\n" else acc + [elem], re.split("(\n)", "a\nb\nc\n"), [])
यहाँ परिणाम है:
['a\n', 'b\n', 'c\n', '']
ध्यान दें कि यह एसओ में लोकप्रिय जवाब देने वाले किनारे के मामलों को संभालता है। अधिक गहराई से स्पष्टीकरण के लिए, मैं आपको मूल ब्लॉग पोस्ट पर पुनः निर्देशित कर रहा हूं।
यदि तिथियों की सूची लगातार है, तो यह जानने के लिए कम () का उपयोग करें:
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"
from functools import reduce
समान कोड को Python 2 और 3.