python 几何级数

1 投票
4 回答
7567 浏览
提问于 2025-04-17 17:00

我正在尝试解决一本书中的一个问题,但我完全不知道该怎么做。问题是,写一个名为 geometric() 的函数,这个函数接收一个整数列表作为输入,如果这个列表中的整数形成一个等比数列,就返回 True。一个数列 a0, a1, a2, a3, a4,..., an-2, an-1 是等比数列,当且仅当它们的比值 a1/a0, a2/a1, a3/a2, a4/a3,..., an-1/an-2 都相等。

def geometric(l):
for i in l:
    if i*1==i*0:
        return True
else:
    return False

说实话,我完全不知道该从哪里开始,脑子一片空白。任何帮助都将不胜感激。

谢谢!

举个例子:

geometric([2,4,8,16,32,64,128,256])
>>> True

geometric([2,4,6,8])`
>>> False

4 个回答

1

这是我的解决方案。其实和pyrospade的itertools代码差不多,只不过我把生成器拆开了。作为额外的好处,我可以完全使用整数运算,避免了任何除法运算(因为在理论上,这可能会导致浮点数的舍入问题):

def geometric(iterable):
    it = iter(iterable)
    try:
        a = next(it)
        b = next(it)
        if a == 0 or b == 0:
            return False
        c = next(it)
        while True:
            if a*c != b*b: # <=> a/b != b/c, but uses only int values
                return False
            a, b, c = b, c, next(it)
    except StopIteration:
        return True

一些测试结果:

>>> geometric([2,4,8,16,32])
True
>>> geometric([2,4,6,8,10])
False
>>> geometric([3,6,12,24])
True
>>> geometric(range(1, 1000000000)) # only iterates up to 3 before exiting
False
>>> geometric(1000**n for n in range(1000)) # very big numbers are supported
True
>>> geometric([0,0,0]) # this one will probably break every other code
False
1

一种简单的方法可以这样做:

def is_geometric(a):
    r = a[1]/float(a[0])
    return all(a[i]/float(a[i-1]) == r for i in xrange(2,len(a)))

基本上,它计算前两个数字之间的比例,然后使用 all 来判断生成器中的所有成员是否都为真。生成器中的每个成员都是一个布尔值,表示两个数字之间的比例是否等于前两个数字之间的比例。

3

这段代码应该能高效地处理所有可迭代的对象。

from itertools import izip, islice, tee

def geometric(obj):
    obj1, obj2 = tee(obj)
    it1, it2 = tee(float(x) / y for x, y in izip(obj1, islice(obj2, 1, None)))
    return all(x == y for x, y in izip(it1, islice(it2, 1, None)))

assert geometric([2,4,8,16,32,64,128,256])
assert not geometric([2,4,6,8])

可以看看 itertools 这个库 - http://docs.python.org/2/library/itertools.html

撰写回答