为什么我的功能并不总是返回正确的列表?

时间:2013-05-04 18:43:22

标签: python list function tuples

我有一个带两个输入的函数,它将返回一个元组数组,其中给定元组中的两个数字与赋予函数的两个数字具有完全相同的比率!

所以一切都运行正常,但出于某种原因,在某些情况下,它并没有取得每个元组。这是一个例子,我不知道为什么:

In [52]: def find_r(num1,num2):
   ....:         ratio = num1/float(num2)
   ....:         ratio = 1/ratio
   ....:         my_list = [(a,int(a * ratio)) for a in range(1,num1) if float(a * ratio).is_integer()] #and a * 1/float(ratio) + a <= num1]
   ....:         return my_list
   ....: 

In [53]: find_r(100,364)
Out[53]: [(75, 273)]

所以它只返回一个元组,但是如果你将75和273除以3,你会得到一个25和91的元组,它们具有相同的比率!为什么我的函数没有拿起这个实例?

如果有帮助,我怀疑它与is_integer()方法有关,但我不太确定。

谢谢!

2 个答案:

答案 0 :(得分:5)

这是由于浮点运算的不精确性:

>>> ((100/364)*364).is_integer()
False
>>> ((25/91)*91).is_integer()
False

不应该做你正在做的事情,而应该通过交叉乘法来检查分数的等价性。也就是说,给定分数a/b,检查它是否等同于另一个c/d,检查是否ad == bc。这将避免分裂并将所有内容保持为整数。

你可以这样做:

def find_r(num1,num2):
    return [(a, a*num2//num1) for a in range(1, num1) if (a*num2) % num1 == 0]

>>> find_r(100, 364)
[(25, 91), (50, 182), (75, 273)]

(还有其他方法可以完成你的任务,但这与你原来的方法最相似。)

答案 1 :(得分:0)

我认为你得到了你期望的答案

>>> r=100/float(364)
>>> r
0.27472527472527475
>>> r=1/r
>>> r
3.6399999999999997
>>> r*25
90.99999999999999
>>> r*75
273.0

要进行整数检查,可以使用

if(int(a*ratio) == a*ratio)喜欢

def find_r(num1,num2):
       ratio = num1/float(num2)
       ratio = 1/ratio
       my_list = [(a,int(a * ratio)) for a in range(1,num1) if int(a * ratio) == a * ratio] 
       for a in range(1,num1):
           if int(a * ratio) == a * ratio:
               print a * ratio
       return my_list


print find_r(100,364)