Python迭代器无法按预期工作

时间:2015-05-01 00:10:08

标签: python generator iterable

我有以下代码,我试图比较一些值并返回最高值:

def high(it):
    it = iter(it)
    returnlist = []
    try:
        while True:
            one = next(it)
            two = next(it) 
            three = next(it)
            if three <= two and one <= two:
                returnlist.append(two)
    except StopIteration:
        pass
    return returnlist

它已经完成了一半,但没有正确使用:

>>high([0,1,-1,3,8,4,3,5,4,3,8]) #(this works)
[1, 8, 5] 
>>high([5,2,4,9,6,1,3,8,0,7]) #(this doesn't work, should return [9,8]
[8] 
>>high(int(is_prime(p)) for p in irange(1,20)) #(doesn't work, returns four 1's - should return 5)
[1, 1, 1, 1]

2 个答案:

答案 0 :(得分:1)

您的代码正在做的是划分&#34;列表&#34;分成3块,只比较每个块中的数字。这意味着您只将前3个数字相互比较,然后将下3个数字相互比较。你想要做的是使用一个滑动窗口,以便将每个数字与旁边的数字进行比较。您可以通过跟踪以前的值来执行此操作:

def high(lst):
    returnlist = []
    one = None
    two = None
    for three in lst:
        # If one is None here we haven't
        # reached the first set of numbers yet
        if not one is None: 
            if three <= two and one <= two:
                returnlist.append(two)
        # Update the sliding window
        one = two
        two = three
    return returnlist

答案 1 :(得分:1)

@Shashank评论是正确的,因为你假设迭代器是独立的,当它们不是时。您可以使用tee修补您的功能:

from itertools import tee

def high(it):

    it1,it2,it3 = tee(iter(it), 3)
    next(it2, None)
    next(it3, None); next(it3, None)

    returnlist = []
    try:
        while True:
            one = next(it1)
            two = next(it2) 
            three = next(it3)
            if three <= two and one <= two:
                returnlist.append(two)
    except StopIteration:
        pass
    return returnlist

我认为实现相同想法的更加抒情的方式是:

from itertools import tee, izip

def threesome(iterable):
    "s -> (s0,s1,s2), (s1,s2,s3), (s2,s3,s4), ..."
    a, b, c = tee(iterable, 3)
    next(b, None)
    next(c, None); next(c, None)
    return izip(a, b, c)

def high(it):
    return [x2 for x1, x2, x3 in threesome(it) if x2 == max(x1, x2, x3)]

顺便说一下,我认为最后一个案例的预期输出是不正确的。你应该在输出中看到零,因为这会在你连续有三个复合数字的时候发生(例如8,9,10会满足你的条件)。