2013-05-04 19 views
0

我有一个函数需要两个输入,并将返回一个元组数组,其中给定元组中的两个数字与赋给该函数的两个数字具有完全相同的比率!为什么我的函数不总是返回正确的列表?

所以一切工作正常,但由于某种原因,在某些情况下,它不拾取每个元组。下面是它的一个例子,我不知道为什么:

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()方法有关,但我不太确定。

谢谢!

回答

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)] 

(还有其他的方法来完成你的任务,但是这是最相似的原始的做法。)

+0

这是有道理的,但不幸的是,我不能检查分数的等价,因为我在做基于具有完全相同的比例项的列表。我只需要清除我所做的非整数,但正如您所指出的那样,某些整数看起来像浮点数,这是我的问题。 – 2013-05-04 18:50:09

+1

@RyanSaxe:比例是一个分数。看到我编辑的答案的方式来做到这一点。 – BrenBarn 2013-05-04 18:57:40

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) 
相关问题