除了StopIteration: has_v1 = False 试试: v2 = i2.next() has_v2 = True 除了StopIteration: has_v2 = False #只要我们从两个值获得值/迭代器/无论如何, 比较并得出最低的 #two,然后得到来自相应来源的下一个值 而has_v1和has_v2: #找出v1和v2中的哪一个首先 如果比较器不是无: comp = comparer(v1,v2) 如果comp< = 0: yield_v1 = True else: yield_v1 = False else: 如果v1< = v2: yield_v1 =真的 否则: yield_v1 =错误 #产生下一个值,然后从 对应来源 如果yield_v1: 收益率v1 尝试: v1 = i1。 next() 除了StopIteration: has_v1 = False else: yield v2 试试: v2 = i2.next() 除了StopIteration: has_v2 = False #当我们到达这里时,我们有3种可能性: #1. has_v1 == True,has_v2 == False - >产生剩余的v1 / i1和 只是退出StopIteration异常 #2. has_v1 == False,has_v1 == True - >产生剩余的v2 / i2和 只需退出StopIteration异常 #3。has_v1 == has_v2 == False - > while-loops将跳过,函数 从最终落下 而has_v1: yield v1 v1 = i1.next() 而has_v2: 收益v2 v2 = i2.next() 为了最有效和优雅解决方案,查看Raymond Hettinger的回复: http://aspn.activestate.com/ASPN/Coo.../Recipe/141934 George I need to merge several sources of values into one stream of values. Allof the sources are sorted already and I need to retrieve the values fromthem all in sorted order.In other words:s1 = [10, 20, 30, 40, 50]s2 = [15, 25]s3 = [17, 27, 37]for value in ???(s1, s2, s3):print valuewill print out 10, 15, 17, 20, 25, 27, 30, 37, 40, 50 in that order.The sources are cursors retrieving data from several databases, not fromthe same server, and there''s a potential for a large number of rows fromseveral of the sources. As such, any method that would load it all intomemory and sort it is no good as it would too much memory.Is there a function or whatnot in Python that will do what I want? Ihave come up with my own method but since it uses generators I''m notsure how much overhead there is. Additionally, since the valuesretrieved from the cursors will be dictionaries of "fieldname":valuepairs, the method would either need to handle that construct (and betold what fieldname to sort on), or be able to take a function object touse for the comparison operation.Basically, I''ll use my own function for this unless someone can point meto something that is already available. Couldn''t seem to find anythingin the builtin modules but I didn''t find glob.glob when I was lookingfor how to find filenames either so who knows what it''s called :)Since I need to deal with a variable list of sources (that is, 2 in oneapplication, 3 in another and 4-5 in a third), a simple 2-source methodisn''t enough but if it''s better than what I do for 2 sources then I canmake a wrapper for it, since that''s what I do anyway.--Lasse V?gs?ther Karlsen http://usinglvkblog.blogspot.com/mailto:la***@vkarlsen.noPGP KeyID: 0x2A42A1C2 解决方案I doubt you''ll find a prebuilt one, it''s fairly easy to create your own,after all. Generators are fairly fast constructs in Python, btw.Here''s what I whipped up in a few minutes:def firstIter( value ):it = iter( value )try:return it.next(), itexcept StopIteration, err:return None, Nonedef inorder( comparision, *args ):iterators = [[value,it]for (value,it) in [ firstIter( arg ) for arg in args ]if it is not None]iterators.sort()while iterators:yield iterators[0][0]try:value = iterators[0][0] = iterators[0][1].next()except StopIteration, err:iterators.pop(0)else:if len(iterators) > 1 and comparision( value,iterators[1][0]) == 1:iterators.sort()continueif __name__ == "__main__":s1 = [10, 20, 30, 40, 50]s2 = [15, 25]s3 = [17, 27, 37]s4 = []for value in inorder(cmp, s1, s2, s3, s4):print valueAnyway, have fun,Mike--________________________________________________Mike C. FletcherDesigner, VR Plumber, Coder http://www.vrplumber.com http://blog.vrplumber.com@type comparer: function-object, example: lambda x, y: x-y@note: The "list of iterables" can actually be anything thatproduces a list of iterables, so you canuse a function that yields lists for instance."""# First convert whatever we''re given into a list of sourcesiterables = [iterable for iterable in iterables]# This series of if-statements will determine how many sources wehave and work out sub-problems# that are manageable.if len(iterables) != 2:if len(iterables) == 0:# List, but no sourcespasselif len(iterables) == 1:# Only 1 source, just return its contentsfor value in iterables[0]:yield valueelif len(iterables) == 3:# 3 sources, sub-divide into 0 <--> (1, 2)left_iterable = iterables[0]right_iterable = merge_sorted([iterables[1], iterables[2]],comparer)for value in merge_sorted([left_iterable, right_iterable],comparer):yield valueelif len(iterables) == 4:# 4 sources, sub-divide into (0, 1) <--> (2, 3)left_iterable = merge_sorted([iterables[0], iterables[1]],comparer)right_iterable = merge_sorted([iterables[2], iterables[3]],comparer)for value in merge_sorted((left_iterable, right_iterable),comparer):yield valueelif len(iterables) > 4:# >4 sources, sub-divide into (0, 1) <--> (2, ...)left_iterable = merge_sorted([iterables[0], iterables[1]],comparer)right_iterable = merge_sorted(iterables[2:], comparer)for value in merge_sorted((left_iterable, right_iterable),comparer):yield valueraise StopIteration# The method will only get here if there is only two sources, whichis an easy case to handlei1 = iter(iterables[0])i2 = iter(iterables[1])# Grab the first two values from the two sources, if possibletry:v1 = i1.next()has_v1 = Trueexcept StopIteration:has_v1 = Falsetry:v2 = i2.next()has_v2 = Trueexcept StopIteration:has_v2 = False# As long as we got values from both generates/iterators/whatever,compare and yield the lowest of the# two, and then get the next value from the corresponding sourcewhile has_v1 and has_v2:# Work out which of v1 and v2 comes firstif comparer is not None:comp = comparer(v1, v2)if comp <= 0:yield_v1 = Trueelse:yield_v1 = Falseelse:if v1 <= v2:yield_v1 = Trueelse:yield_v1 = False# Yield the next value, then grab a new value from thecorresponding sourceif yield_v1:yield v1try:v1 = i1.next()except StopIteration:has_v1 = Falseelse:yield v2try:v2 = i2.next()except StopIteration:has_v2 = False# When we get here, we got 3 possibilities:# 1. has_v1 == True, has_v2 == False --> yield rest of v1/i1 andjust exit on StopIteration exception# 2. has_v1 == False, has_v1 == True --> yield rest of v2/i2 andjust exit on StopIteration exception# 3. has_v1 == has_v2 == False --> while-loops will skip, functionfalls off the endwhile has_v1:yield v1v1 = i1.next()while has_v2:yield v2v2 = i2.next()For the most efficient and elegant solution, check out Raymond Hettinger''s reply to: http://aspn.activestate.com/ASPN/Coo.../Recipe/141934George 这篇关于将排序列表/迭代器/生成器合并为一个值流...的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持! 上岸,阿里云!
08-20 12:37
查看更多