本文介绍了评论PEP-0322:反向迭代方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述 29岁程序员,3月因学历无情被辞! 请评论新PEP的反向迭代方法。 基本上,这个想法是这样的: $ x $ b for x in xrange(10)。 iter_backwards():#9,8,7,6,5,4,3,2,1,0 <用i做某事> HTML版本比ReST版本更易读。 请参阅: http://www.python.org/peps/pep-0322.html 在pre-pep线程中出现了几个有趣的想法: *称之为ireverse()而不是iter_backwards()。 好​​主意。这是非常精辟的。 *使用对象属性而不是方法。 我还不能声称理解作者真的是什么/> 提议。它有一些事情可以提供 访问一个响应iter,getitem和 每个反转索引的物品的对象。 *使用单个函数,查找__riter__ magic 方法,如果没有找到,使用__getitem__和__len__ 来构建反向迭代器。 发布了一个可行的版本。 它保存了实现一些对象方法的 添加新的内置函数和 创建一个新的魔术方法名称。 它比直接访问底层对象要慢。 应用于无限迭代器时崩溃。 应用于映射时会产生奇怪的结果。 *无限迭代器的特殊标记 这个想法很有意思,但并没有很好的延伸 当对象被另一个迭代器包裹时。 另外,没有自动的方法来确定 哪个基因rators可以是无限的。 Raymond HettingerPlease comment on the new PEP for reverse iteration methods.Basically, the idea looks like this:for i in xrange(10).iter_backwards(): # 9,8,7,6,5,4,3,2,1,0<do something with i>The HTML version is much more readable than the ReST version.See: http://www.python.org/peps/pep-0322.htmlSeveral interesting ideas surfaced in the pre-pep thread:* Call it ireverse() instead of iter_backwards().Good idea. This is much more pithy.* Use object properties instead of methods.I can''t yet claim to understand what the author is reallyproposing. It has something to do which providingaccess to an object that responds to iter, getitem, andgetslice with reversed indices.* using a single function that looks for an __riter__ magicmethod and, if not found, use __getitem__ and __len__to build a reverse iterator.A workable version of this was posted.It saves implementing some object methods at theexpense of adding a new builtin function and ofcreating a new magic method name.It is slower than direct access to the underlying object.It crashes when applied to an infinite iterator.It produces bizarre results when applied to mappings.* special markers for infinite iteratorsThis idea is interesting but doesn''t extend wellwhen the object is wrapped by another iterator.Also, there is no automatic way to determinewhich generators can be infinite.Raymond Hettinger推荐答案 来自PEP 322的# """ 拒绝替代想法 [snip] 添加内置函数,reverse()...... """ 你的意思是将函数reverse()(或ireverse())添加到itertools 库中,或添加到__builtins__?# from PEP 322"""Rejected Alternative Ideas[snip]Add a builtin function, reverse() ..."""Do you mean add a function reverse() (or ireverse()) to the itertoolslibrary, or to __builtins__? 这个想法基本上有一种方法可以获得一个序列的代理,这个序列与原始序列的行为类似,但索引相反。有 是没有理由为什么成员函数不能返回那些代理 而不是使用属性,除非结果被切成它 看起来不那么难看。 我只为列表演示了它(在帖子末尾列出)。它有 三个属性... 向后:反转,切片返回一个列表 ibackward:反转,切片返回一个迭代器 iforward:forward,切片返回迭代器 目前所有属性都支持__getitem __,__ setitem__, __delitem __,_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ,__iter__和__len__(它们都返回 一个相同代理类的实例,但设置了不同的选项)。 对于简单的迭代迭代,我将使用与PEP284 线程相同的原则。 object-acting-as-sliceable-set-of-all-integers idea。 我在切片翻译工作时遇到了一些问题 - 有一些带有负面步骤的小恶作剧。你可以写... x [:: - 1] ....但是试图让它明确...... x [len(x)-1:-1:-1] ....因为-ve stop bound而打破它。不是一个数字用户, 切片步骤对我来说是一个很新的事情 - 而那个小陷阱只是 让我感到惊讶。但是,解决它并不困难。 下面的代码并不是很好,但据我所知它可行。 $ b假设$ b Python 2.3。 问题是 - 练习是值得的。我不确定即使这是我自己的想法。我认为它的方式很好,并且比'iter_backward''方法提案更灵活,但是这非常可靠,因为它可能是一件坏事对于这个问题来说可能是一次性的过度杀伤 正在解决 - 特别是额外的灵活性有成本。 但是到底怎么样 - 玩起来很有趣有点! 无论如何,这是一个快速测试会议......The idea is basically to have a way to get a proxy to a sequence whichbehaves like the original sequence, but with indexes reversed. Thereis no reason why member functions couldn''t return those proxiesinstead of using properties, except that when the result is sliced itlooks less ugly.I have a demo of it for lists only (listing at end of post). It hasthree properties...backward : reversed, slicing returns a listibackward : reversed, slicing returns an iteratoriforward : forward, slicing returns an iteratorAll properties currently support __getitem__, __setitem__,__delitem__, __str__, __repr__, __iter__ and __len__ (they all returnan instance of the same proxy class but with different options set).For simple iterating-over-ints, I''d use the same principles with thatobject-acting-as-sliceable-set-of-all-integers idea from the PEP284thread.I had some problems getting the slice translation to work - there aresome little nasties with negative steps. You can write...x [::-1]....but trying to make it explicit...x [len(x)-1:-1:-1]....breaks it because of that -ve stop bound. Not being a Numeric user,slice steps are quite a new thing to me - and that little trap justcaught me by surprise. It isn''t too hard to work around it, though.The code following isn''t pretty but so far as I can tell it works.Python 2.3 is assumed.The question is - is the exercise worthwhile. I''m not sure even thoughit''s my own idea. I think it is nice in its way, and a lot moreflexible than the ''iter_backward'' method proposal, but that is quitelikely a bad thing as it is probably massive overkill for the problembeing solved - and in particular the extra flexibility has costs.What the hell, though - it was fun to play with for a bit!Anyway, here is a quick test session... ....打印我 。 ... 10 12 14 16 18 我也做了一些'ibackward''测试,这似乎有用 - 但是 我没有被''iforward''烦恼。 这是源 - 警告,它不是非常自我记录的ATM ...... class c_List_Proxy(object): " ;" 代理列出类,它支持具有 修改行为的方法子集,主要是...... - 切片可能会创建一个迭代器而不是列表。 - 下标和范围可能会颠倒。 """ def __init__(self,p_List,p_Reverse = False,p_Iter_Slice = False): self.List = p_List self.Reverse = p_Reverse self.Iter_Slice = p_Iter_Slice #需要一些支持的东西 def __SliceIter__(self,p_Slice): 如果p_Slice.step> 0: i = p_Slice.start 而i< p_Slice.stop: 收益self.List [i] i + = p_Slice.step else: i = p_Slice.start 而我> p_Slice.stop: 产生self.List [i] i + = p_Slice.step def __FullIter__(self): i = len(self.List) - 1 而i> = 0: 产生self.List [i] i - = 1 def __KeyTransformed__(self,p_Key): if self.Reverse: if p_Key< 0: 返回(-1) - p_Key else: return(len(self.List) - 1) - p_Key else: 返回p_Key def __Bound__(self,p_Given,p_Default):: 返回p_Default elif p_Given< 0: 返回len(self.List)+ p_Given 否则: 返回p_Given def __SliceFixed __(self,p_Slice): l_Step = p_Slice.step或1 如果l_Step == 0: 提高IndexError,步骤必须为非零 elif l_Step> 0: l_Start = self .__ Bound __(p_Slice.start,0) l_Stop = self .__ Bound __(p_Slice.stop,len(self.List)) else: l_Start = self .__ Bound __(p_Slice.start,len(self.List) - 1) l_Stop = self。 __Bound __(p_Slice.stop,-1) l_Count =(((l_Stop - 1) - l_Start)// l_Step)+ 1 l_Stop = l_Start + l_Count * l_Step 返回切片(l_Start,l_Stop,l_Step) def __SliceTransformed__(self,p_Slice): l_Slice = self .__ SliceFixed __(p_Slice) if self.Reverse: l_End = len(self.List) - 1 返回切片(l_End - l_Slice.start,l_End - l_Slice.stop, -l_Slice.step) else: 返回p_Slice #有些成员很琐碎 def __len__(个体经营): 返回len(self.List) def __iter __(自我): 返回自我.__ FullIter __() #一些成员需要多做一些工作... def __str __(自我): if self.Reverse: return str(self.List [:: - 1]) else: return str(self.List) def __repr__(self): if self.Reverse: return repr(self.List [:: - 1]) else: 返回repr(self.List) def __getitem __(self,p_Item): if isinstance(p_Item,slice) : 如果self.Iter_Slice: 返回self .__ SliceIter__(self .__ SliceTransformed__(p_Item)) else: l_Slice = self .__ SliceTransformed__(p_Item) 如果l_Slice.stop == -1:#烦人的特殊情况 返回自我。列表[l_Slice.start :: l_Slice.step] 返回self.List [l_Slice.start:l_Slice.stop:l_Slice.step] else: 返回self.List [self .__ KeyTransformed__(p_Item)] def __setitem __(self,p_Item,p_Value): if isinstance(p_Item,slice): l_Slice = self .__ SliceTransformed__(p_Item) if l_Slice.stop == -1:#anboying特例 self.List [l_Slice.start :: l_Slice.step] = p_Value else: self.List [l_Slice.start :l_Slice.stop:l_Slice.step] = p_Value else: self.List [self .__ KeyTransformed__(p_Item)] = p_Value def __delitem __(self,p_Item): if isinstance(p_Item,slice): l_Slice = self .__ SliceTransformed__(p_Item) 如果l_Slice.stop == -1:#烦人的特殊情况 del self.List [l_Slice.start :: l_Slice.step] else: del self.List [l_Slice.start:l_Slice.stop:l_Slice.step] else: del self.List [self .__ KeyTransformed__(p_Item)] class rilist(list): """ 扩展正常列表以提供给出正常变体的属性 索引行为 - 具体来说...... 索引切片返回 -------- -------- ------- iforward forward iterator ibackward落后迭代器 后退列表 " " def __IFwd__(自我): 返回c_List_Proxy(self,False,True) def __IBack __(自我): 返回c_List_Proxy(self,True,True) def __Back__(自我): 返回c_List_Proxy(self ,正确,错误) iforward = property(__ IFwd__) ibackward = property(__ IBack__) 落后=财产(__ Back__ ) - 史蒂夫·霍恩 史蒂夫在九点点fsnet dot co uk.... print i....1012141618I''ve done some ''ibackward'' tests as well, and that seems to work - butI haven''t bothered with ''iforward''.Here is the source - warning, it isn''t very self-documenting ATM...class c_List_Proxy (object) :"""Proxy to list class which supports a subset of methods withmodified behaviours, mainly...- Slicing may create an iterator rather than a list.- Subscripts and ranges may be reversed."""def __init__ (self, p_List, p_Reverse=False, p_Iter_Slice=False) :self.List = p_Listself.Reverse = p_Reverseself.Iter_Slice = p_Iter_Slice# need some support stuffdef __SliceIter__ (self, p_Slice) :if p_Slice.step > 0 :i = p_Slice.startwhile i < p_Slice.stop :yield self.List [i]i += p_Slice.stepelse :i = p_Slice.startwhile i > p_Slice.stop :yield self.List [i]i += p_Slice.stepdef __FullIter__ (self) :i = len (self.List) - 1while i >= 0 :yield self.List [i]i -= 1def __KeyTransformed__ (self, p_Key) :if self.Reverse :if p_Key < 0 :return (-1) - p_Keyelse :return (len (self.List) - 1) - p_Keyelse :return p_Keydef __Bound__ (self, p_Given, p_Default) :if p_Given is None :return p_Defaultelif p_Given < 0 :return len (self.List) + p_Givenelse :return p_Givendef __SliceFixed__ (self, p_Slice) :l_Step = p_Slice.step or 1if l_Step == 0 :raise IndexError, "Step must be non-zero"elif l_Step > 0 :l_Start = self.__Bound__ (p_Slice.start, 0)l_Stop = self.__Bound__ (p_Slice.stop, len (self.List))else :l_Start = self.__Bound__ (p_Slice.start, len (self.List) - 1)l_Stop = self.__Bound__ (p_Slice.stop, -1)l_Count = (((l_Stop - 1) - l_Start) // l_Step) + 1l_Stop = l_Start + l_Count * l_Stepreturn slice(l_Start,l_Stop,l_Step)def __SliceTransformed__ (self, p_Slice) :l_Slice = self.__SliceFixed__ (p_Slice)if self.Reverse :l_End = len(self.List) - 1return slice (l_End - l_Slice.start, l_End - l_Slice.stop,-l_Slice.step)else :return p_Slice# some members are trivialdef __len__ (self) :return len (self.List)def __iter__ (self) :return self.__FullIter__ ()# some members need a bit more work...def __str__ (self) :if self.Reverse :return str(self.List [::-1])else :return str(self.List)def __repr__ (self) :if self.Reverse :return repr(self.List [::-1])else :return repr(self.List)def __getitem__ (self, p_Item) :if isinstance (p_Item, slice) :if self.Iter_Slice :return self.__SliceIter__ (self.__SliceTransformed__ (p_Item))else :l_Slice = self.__SliceTransformed__ (p_Item)if l_Slice.stop == -1 : # annoying special casereturn self.List [l_Slice.start::l_Slice.step]return self.List [l_Slice.start:l_Slice.stop:l_Slice.step]else :return self.List [self.__KeyTransformed__ (p_Item)]def __setitem__ (self, p_Item, p_Value) :if isinstance (p_Item, slice) :l_Slice = self.__SliceTransformed__ (p_Item)if l_Slice.stop == -1 : # annoying special caseself.List [l_Slice.start::l_Slice.step] = p_Valueelse :self.List [l_Slice.start:l_Slice.stop:l_Slice.step] = p_Valueelse :self.List [self.__KeyTransformed__ (p_Item)] = p_Valuedef __delitem__ (self, p_Item) :if isinstance (p_Item, slice) :l_Slice = self.__SliceTransformed__ (p_Item)if l_Slice.stop == -1 : # annoying special casedel self.List [l_Slice.start::l_Slice.step]else :del self.List [l_Slice.start:l_Slice.stop:l_Slice.step]else :del self.List [self.__KeyTransformed__ (p_Item)]class rilist (list) :"""Extend normal list to provide properties giving variants of normalindexing behaviour - specifically...indexing slicing returns-------- ---------------iforward forward iteratoribackward backward iteratorbackward backward list"""def __IFwd__ (self) :return c_List_Proxy (self, False, True)def __IBack__ (self) :return c_List_Proxy (self, True, True)def __Back__ (self) :return c_List_Proxy (self, True, False)iforward = property(__IFwd__ )ibackward = property(__IBack__)backward = property(__Back__ )--Steve Hornesteve at ninereeds dot fsnet dot co dot uk 这篇关于评论PEP-0322:反向迭代方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持! 上岸,阿里云!
08-23 04:27