-1

我今天进行了一项测试,并提出了一个问题:编写函数 doubles(),它将整数列表作为输入,并输出列表中的整数,该整数恰好是列表中前一个整数的两倍,每行一个。

我无法弄清楚我的代码是如何做到这一点的

def doubles(x):
    for a in range(len(x)-1):
        for b in (range(a,len(x))):
            if x[a]*2==x[b]:
                print(b)

例如 doubles([3,0,1,2,3,6,2,4,5,6,5]) 将打印 2 , 6 , 4

有人可以帮我弄清楚如何做到这一点吗?

4

6 回答 6

1
def doubles(lst):
    prev = None
    for actual in lst:
        if prev is not None and actual == 2*prev:
            print actual
        prev = actual
于 2013-03-20T19:32:09.517 回答
1

这可以很简单地完成:

def doubles(seq):
    after = seq[1:]
    for previous, current in zip(seq, after):
        if current == previous * 2:
            print(current)

哪个按预期工作:

>>> print(list(doubles([3, 0, 1, 2, 3, 6, 2, 4, 5, 6, 5])))
2
6 
4

我们从列表的一部分中获取第二个列表中的值列表。然后,我们使用zip()前一个值循环遍历每个值,并简单地执行检查,如果匹配,则打印该值。

您也可以通过替换来将其构造为生成器print()yield这通常是一个更好的选择),或者如果您真的想要一个列表:

def doubles(seq):
    after = seq[1:]
    return [current for previous, current in zip(seq, after) 
            if current == previous * 2]
于 2013-03-20T19:33:04.643 回答
1

您的代码是将每个值与列表中稍后出现的所有值进行比较。但是这个问题要求你只考虑相邻的对。

因此,您只需要遍历列表一次。像这样:

def doubles(x):
    for i in range(1, len(x)):
        if x[i] == 2*x[i-1]:
            print x[i]

更重要的是,您的代码打印了索引而不是值,这是我在上面修复的一个错误。

于 2013-03-20T19:27:54.167 回答
1

您只需要遍历列表一次,用它之后的一个或之前的一个来测试每个元素。

下面的示例用它后面的数字测试每个数字,并在最后一个数字处停止。

def doubles(x):
    for i,a in enumerate(x[:-1]):
        if x[i+1] == a*2:
            print a*2
于 2013-03-20T19:31:16.690 回答
1

最简单的方法是使用一个元素移位进行压缩并检查元素对是否符合您的条件

>>> def doubles(x):
    return [b for a,b in zip(x,x[1:]) if b == 2*a]

>>> for e in doubles([3,0,1,2,3,6,2,4,5,6,5]):
    print e


2
6
4

类似的解决方案,但只使用迭代器

>>> def doubles(x):
    it1, it2 = tee(x)
    next(it2)
    return [b for a,b in izip(it1,it2) if b == 2*a]

>>> for e in doubles([3,0,1,2,3,6,2,4,5,6,5]):
    print e


2
6
4
于 2013-03-20T19:35:29.300 回答
0

您不需要嵌套循环。对于每个元素,您只需要针对它之前的元素对其进行测试。

于 2013-03-20T19:30:44.837 回答