[英]Why is elif running before if statement? Python
项目Euler问题33要求求解器找到“好奇分数”:这些分数等于通过删除分子和分母中同时出现的数字而获得的分数(例如49/98,通过删除数字将其“取消”为4/8) 9s)。
注意:这不是解决Project Euler问题最快的竞赛。 我已经将此代码重写为一个与Nickie一样快的解决方案。 这是通过删除for循环和if float(numer)...条件来完成的。 看起来像这样:
def curious(numer,denom):
n = str(numer)
d = str(denom)
if len(n) == 2 and len(d) == 2:
if n[1] == d[0]:
if n != d:
if d[1] != "0":
if Fraction(int(n[0]), int(d[1])) \
== \
Fraction(numer, denom):
return n + d
我仍然不理解条件问题。
我对Python编程并不陌生,这是我第一次遇到这样的事情。 在下面定义的函数中,有成对的if和elif语句:
import time
from fractions import Fraction
def curious(numer,denom):
n = str(numer)
d = str(denom)
if len(n) == 2 and len(d) == 2:
if n[1] == d[0]:
for i in range(2, numer+1):
if float(numer)/i == float(int(n[0])) \
and float(denom)/i == float(int(d[1])):
if n != d:
return n + "/" + d
elif d[1] != "0":
if Fraction(int(n[0]), int(d[1])) \
== \
Fraction(numer, denom):
if n != d:
return n + d
start = time.time()
nums = []
denoms = []
for i in range(10, 100):
for j in range(10, 100):
if i < j:
if type(curious(i, j)) == str:
frac = (curious(i,j))
nums.append(frac[0]+frac[1])
denoms.append(frac[2]+frac[3])
print frac
pro = 1
duct = 1
for i in range(0, len(nums)):
pro *= int(nums[i])
duct *= int(denoms[i])
print Fraction(pro, duct)
elapsed = time.time() - start
print "The elapsed time is %s seconds." % (elapsed)
当我在注释掉elif语句的情况下运行代码时,结果是这样的:
16/64,
19/95,
26/65,
The elapsed time is 0.0500001907349 seconds.
但是,当包含elif时,if语句将被忽略,结果是这样的:
1664,
1995,
2665,
4998,
The elapsed time is 0.59700012207 seconds.
似乎Python倾向于采用低效率的路由,即使在两种情况下均满足if语句的条件。 谁能帮我解决这个难题?
理想情况下,我希望结果为:
16/64,
19/95,
26/65,
4998,
The elapsed time is 0.0500001907349 seconds.
这是一个奇怪的结构化答案,因为它是增量编写的。 我为此表示歉意。 即使这样,我还是值得按此顺序阅读。 每个部分都用水平尺隔开,各有不同。
浮点算法中的相等比较是常见的麻烦来源,应避免使用。 代替测试:
float(numer)/i == float(int(n[0])) and float(denom)/i == float(int(d[1]))
为什么不以下? 更简单和等效(在数学中,但在Python中不!):
numer == i * int(n[0]) and denom == i * int(d[1])
最重要的是,不仅浮点运算会带来麻烦,而且从int
到float
太频繁也不利于性能。
我不明白为什么您希望您的程序在删除elif
子句时能输出相同的结果。 当您拥有和没有elif
时,它会执行两种不同的操作。 您只是返回相同的结果(n / d),所以看不到差异。
if
语句未“被绕过”。 但是,如果它在for
循环的第一次迭代中未返回任何内容,则elif
语句(在每次迭代中执行相同的操作)将有机会返回其值。 然后, if
语句将不再执行。
由于现在已经提供了有关该问题的更多信息(这是作为对Euler项目的问题#33的解决方案的一部分),我将继续使用该问题的原始版本,并尝试重构curious
函数,我认为这是写得不好的。 我相信以下函数是等效的,并且速度更快,因为for
循环仅计算依赖于i
事物:
def curious(numer,denom):
n = str(numer)
d = str(denom)
if len(n) == 2 == len(d) and n[1] == d[0] and n != d:
for i in range(2, numer+1):
if numer == i*int(n[0]) and denom == i*int(d[1]):
return n + "/" + d
elif i == 2 and d[1] != "0":
if Fraction(int(n[0]), int(d[1])) == Fraction(numer, denom):
return n + d
使用此功能,Cawb07的程序可以更快地产生相同的输出(四个分数加1/100,这是问题的答案)。
既然我了解了curious
正在尝试做什么,那么让我提出一个更好的方法。 让我们假设要寻求一种蛮力解决方案。 它可以很容易地进行排列,以便总是使用两个两位数的参数来调用curious
,其numer < denom
为true,并且它返回一个布尔结果,表示该分数是否为curious。 此外,没有必要为一个for
循环的curious
,这可以大大简化。
import time
from fractions import Fraction
def curious(numer, denom):
n = str(numer)
d = str(denom)
return (n[0] == d[1] != '0' and denom * int(n[1]) == numer * int(d[0])) \
or (n[0] == d[0] != '0' and denom * int(n[1]) == numer * int(d[1])) \
or (n[1] == d[0] != '0' and denom * int(n[0]) == numer * int(d[1])) \
or (n[1] == d[1] != '0' and denom * int(n[0]) == numer * int(d[0]))
start = time.time()
for i in range(10, 100):
for j in range(i+1, 100):
if curious(i, j):
print i, "/", j
elapsed = time.time() - start
print "The elapsed time is", elapsed, "seconds."
该程序仅打印四个奇怪的分数,比上一个要快得多。
还要注意,为了将好奇分数的乘积减少到最低的公共术语,您可以轻松地计算出分母和分母,然后除以它们的GCD,这可以使用Euclid算法找到。
Cawb07:也可以使用fractions.gcd(n,d)
:)。
在我的以下代码中,根据提供给ELIF的值, elif section
处于活动状态或停用状态 。
import time
from fractions import Fraction
def curious(numer,denom,disp=None):
n = str(numer)
d = str(denom)
fracs = []
if n!=d and n[1] == d[0]:
ELIF = 1
fn0 = float(n[0])
fd1 = float(d[1])
if disp:
print ('---------------------------------------\n'
'n == %s d == %s\n'
"float('%s'[0]) == %f float('%s'[1]) == %f"
% ( n,d,n,fn0,d,fd1 ) )
for i in range(2, numer+1):
if disp:
print ('i== %2d '
'%s./%2d==%10f %s./%2d==%10f %s' %
(i,n,i,float(n)/i,d,i,float(d)/i,
float(n)/i==fn0 and float(d)/i==fd1) )
if float(numer)/i==fn0 and float(denom)/i==fd1:
if disp:
print (' %s\n'
' - %s/%s returned by if section -' %
('- elif part is active -' if ELIF
else '- elif part is not active -',
n,d))
return n + "/" + d
elif ELIF and d[1] != "0":
if Fraction( n[0] + '/' + d[1] ) \
== \
Fraction(numer, denom):
if disp:
print (' %s\n'
" Fraction('%s/%s') == %s\n"
" Fraction(%s, %s) == %s\n"
' - %s%s returned by elif section -' %
('- elif part is active -' if ELIF
else '- elif part is not active -',
n[0],d[1],Fraction( n[0] + '/' + d[1] ),
numer,denom,Fraction(numer, denom),n,d) )
return n + d
else:
if n+d=='4998':
if disp:
print (' - elif part is active -' if ELIF
else ' - elif part is not active -')
print ' - No convenient divisor found for 49 98 : returned by else section -'
return 'No convenient divisor found for 49 98'
start = time.time()
nums,denoms = [],[]
fracs = []
for i in range(10, 100):
for j in range(10, 100):
if curious(i,j):
frac = (curious(i,j,'display'))
print('frac == %s' % frac)
fracs.append(frac)
deb,end = frac[0:2],frac[-2:]
try:
int(deb)
nums.append(deb)
denoms.append(end)
except:
print "can't record %r==frac[0:2] as numerator" % (deb,)
print '\ndetected :\n %s' % '\n '.join(fracs)
pro,duct = 1,1
print '\nnums ==',nums
print 'denoms ==',denoms
for i in range(0, len(nums)):
pro *= int(nums[i])
duct *= int(denoms[i])
print 'pro,duct ==',pro,duct
print 'Fraction(pro, duct) ==',Fraction(pro, duct)
elapsed = time.time() - start
print "The elapsed time is %s seconds." % (elapsed)
ELIF = 0
结果
---------------------------------------
n == 16 d == 64
float('16'[0]) == 1.000000 float('64'[1]) == 4.000000
i== 2 16./ 2== 8.000000 64./ 2== 32.000000 False
i== 3 16./ 3== 5.333333 64./ 3== 21.333333 False
i== 4 16./ 4== 4.000000 64./ 4== 16.000000 False
i== 5 16./ 5== 3.200000 64./ 5== 12.800000 False
i== 6 16./ 6== 2.666667 64./ 6== 10.666667 False
i== 7 16./ 7== 2.285714 64./ 7== 9.142857 False
i== 8 16./ 8== 2.000000 64./ 8== 8.000000 False
i== 9 16./ 9== 1.777778 64./ 9== 7.111111 False
i== 10 16./10== 1.600000 64./10== 6.400000 False
i== 11 16./11== 1.454545 64./11== 5.818182 False
i== 12 16./12== 1.333333 64./12== 5.333333 False
i== 13 16./13== 1.230769 64./13== 4.923077 False
i== 14 16./14== 1.142857 64./14== 4.571429 False
i== 15 16./15== 1.066667 64./15== 4.266667 False
i== 16 16./16== 1.000000 64./16== 4.000000 True
- elif part is not active -
- 16/64 returned by if section -
frac == 16/64
---------------------------------------
n == 19 d == 95
float('19'[0]) == 1.000000 float('95'[1]) == 5.000000
i== 2 19./ 2== 9.500000 95./ 2== 47.500000 False
i== 3 19./ 3== 6.333333 95./ 3== 31.666667 False
i== 4 19./ 4== 4.750000 95./ 4== 23.750000 False
i== 5 19./ 5== 3.800000 95./ 5== 19.000000 False
i== 6 19./ 6== 3.166667 95./ 6== 15.833333 False
i== 7 19./ 7== 2.714286 95./ 7== 13.571429 False
i== 8 19./ 8== 2.375000 95./ 8== 11.875000 False
i== 9 19./ 9== 2.111111 95./ 9== 10.555556 False
i== 10 19./10== 1.900000 95./10== 9.500000 False
i== 11 19./11== 1.727273 95./11== 8.636364 False
i== 12 19./12== 1.583333 95./12== 7.916667 False
i== 13 19./13== 1.461538 95./13== 7.307692 False
i== 14 19./14== 1.357143 95./14== 6.785714 False
i== 15 19./15== 1.266667 95./15== 6.333333 False
i== 16 19./16== 1.187500 95./16== 5.937500 False
i== 17 19./17== 1.117647 95./17== 5.588235 False
i== 18 19./18== 1.055556 95./18== 5.277778 False
i== 19 19./19== 1.000000 95./19== 5.000000 True
- elif part is not active -
- 19/95 returned by if section -
frac == 19/95
---------------------------------------
n == 26 d == 65
float('26'[0]) == 2.000000 float('65'[1]) == 5.000000
i== 2 26./ 2== 13.000000 65./ 2== 32.500000 False
i== 3 26./ 3== 8.666667 65./ 3== 21.666667 False
i== 4 26./ 4== 6.500000 65./ 4== 16.250000 False
i== 5 26./ 5== 5.200000 65./ 5== 13.000000 False
i== 6 26./ 6== 4.333333 65./ 6== 10.833333 False
i== 7 26./ 7== 3.714286 65./ 7== 9.285714 False
i== 8 26./ 8== 3.250000 65./ 8== 8.125000 False
i== 9 26./ 9== 2.888889 65./ 9== 7.222222 False
i== 10 26./10== 2.600000 65./10== 6.500000 False
i== 11 26./11== 2.363636 65./11== 5.909091 False
i== 12 26./12== 2.166667 65./12== 5.416667 False
i== 13 26./13== 2.000000 65./13== 5.000000 True
- elif part is not active -
- 26/65 returned by if section -
frac == 26/65
---------------------------------------
n == 49 d == 98
float('49'[0]) == 4.000000 float('98'[1]) == 8.000000
i== 2 49./ 2== 24.500000 98./ 2== 49.000000 False
i== 3 49./ 3== 16.333333 98./ 3== 32.666667 False
i== 4 49./ 4== 12.250000 98./ 4== 24.500000 False
i== 5 49./ 5== 9.800000 98./ 5== 19.600000 False
i== 6 49./ 6== 8.166667 98./ 6== 16.333333 False
i== 7 49./ 7== 7.000000 98./ 7== 14.000000 False
i== 8 49./ 8== 6.125000 98./ 8== 12.250000 False
i== 9 49./ 9== 5.444444 98./ 9== 10.888889 False
i== 10 49./10== 4.900000 98./10== 9.800000 False
i== 11 49./11== 4.454545 98./11== 8.909091 False
i== 12 49./12== 4.083333 98./12== 8.166667 False
i== 13 49./13== 3.769231 98./13== 7.538462 False
i== 14 49./14== 3.500000 98./14== 7.000000 False
i== 15 49./15== 3.266667 98./15== 6.533333 False
i== 16 49./16== 3.062500 98./16== 6.125000 False
i== 17 49./17== 2.882353 98./17== 5.764706 False
i== 18 49./18== 2.722222 98./18== 5.444444 False
i== 19 49./19== 2.578947 98./19== 5.157895 False
i== 20 49./20== 2.450000 98./20== 4.900000 False
i== 21 49./21== 2.333333 98./21== 4.666667 False
i== 22 49./22== 2.227273 98./22== 4.454545 False
i== 23 49./23== 2.130435 98./23== 4.260870 False
i== 24 49./24== 2.041667 98./24== 4.083333 False
i== 25 49./25== 1.960000 98./25== 3.920000 False
i== 26 49./26== 1.884615 98./26== 3.769231 False
i== 27 49./27== 1.814815 98./27== 3.629630 False
i== 28 49./28== 1.750000 98./28== 3.500000 False
i== 29 49./29== 1.689655 98./29== 3.379310 False
i== 30 49./30== 1.633333 98./30== 3.266667 False
i== 31 49./31== 1.580645 98./31== 3.161290 False
i== 32 49./32== 1.531250 98./32== 3.062500 False
i== 33 49./33== 1.484848 98./33== 2.969697 False
i== 34 49./34== 1.441176 98./34== 2.882353 False
i== 35 49./35== 1.400000 98./35== 2.800000 False
i== 36 49./36== 1.361111 98./36== 2.722222 False
i== 37 49./37== 1.324324 98./37== 2.648649 False
i== 38 49./38== 1.289474 98./38== 2.578947 False
i== 39 49./39== 1.256410 98./39== 2.512821 False
i== 40 49./40== 1.225000 98./40== 2.450000 False
i== 41 49./41== 1.195122 98./41== 2.390244 False
i== 42 49./42== 1.166667 98./42== 2.333333 False
i== 43 49./43== 1.139535 98./43== 2.279070 False
i== 44 49./44== 1.113636 98./44== 2.227273 False
i== 45 49./45== 1.088889 98./45== 2.177778 False
i== 46 49./46== 1.065217 98./46== 2.130435 False
i== 47 49./47== 1.042553 98./47== 2.085106 False
i== 48 49./48== 1.020833 98./48== 2.041667 False
i== 49 49./49== 1.000000 98./49== 2.000000 False
- elif part is not active -
- No convenient divisor found for 49 98 : returned by else section -
frac == No convenient divisor found for 49 98
can't record 'No'==frac[0:2] as numerator
detected :
16/64
19/95
26/65
No convenient divisor found for 49 98
nums == ['16', '19', '26']
denoms == ['64', '95', '65']
pro,duct == 7904 395200
Fraction(pro, duct) == 1/50
The elapsed time is 2.40599989891 seconds.
ELIF = 1
结果
---------------------------------------
n == 16 d == 64
float('16'[0]) == 1.000000 float('64'[1]) == 4.000000
i== 2 16./ 2== 8.000000 64./ 2== 32.000000 False
- elif part is active -
Fraction('1/4') == 1/4
Fraction(16, 64) == 1/4
- 1664 returned by elif section -
frac == 1664
---------------------------------------
n == 19 d == 95
float('19'[0]) == 1.000000 float('95'[1]) == 5.000000
i== 2 19./ 2== 9.500000 95./ 2== 47.500000 False
- elif part is active -
Fraction('1/5') == 1/5
Fraction(19, 95) == 1/5
- 1995 returned by elif section -
frac == 1995
---------------------------------------
n == 26 d == 65
float('26'[0]) == 2.000000 float('65'[1]) == 5.000000
i== 2 26./ 2== 13.000000 65./ 2== 32.500000 False
- elif part is active -
Fraction('2/5') == 2/5
Fraction(26, 65) == 2/5
- 2665 returned by elif section -
frac == 2665
---------------------------------------
n == 49 d == 98
float('49'[0]) == 4.000000 float('98'[1]) == 8.000000
i== 2 49./ 2== 24.500000 98./ 2== 49.000000 False
- elif part is active -
Fraction('4/8') == 1/2
Fraction(49, 98) == 1/2
- 4998 returned by elif section -
frac == 4998
detected :
1664
1995
2665
4998
nums == ['16', '19', '26', '49']
denoms == ['64', '95', '65', '98']
pro,duct == 387296 38729600
Fraction(pro, duct) == 1/100
The elapsed time is 6.40599989891 seconds.
当ELIF为False时,
if section
返回结果16/64 19/95 26/65
,格式背叛了这个原点。
当ELIF为True时,
elif section
返回结果1664 1995 2665 4998
,它也通过格式显示。
它由elif section
返回的事实使您得出结论, if section
未运行。
您的结论是错误的,因为您错误地认为
“在两种情况下都满足if语句的条件”
不,不是,因为您不允许循环测试i
所有可能值:对于第一个值i==2
,测试结果始终为False,则始终在后面输入elif section
第一个值(尼基已经解释了这一点)。
输入的值是相同的,但没有满足提供相同证据所需的条件。
为了使循环有可能完全运行,有必要使elif section
缩进。
请注意,在下面的代码中,在nums
后面添加frac[0:2]
和在denoms
后面添加frac[0:2]
frac[-2:]
允许执行不会因为错误而停止,并且结果就是您正在等待的结果: 16/64 19/95 26/65 4998
def curious(numer,denom,disp=None):
n = str(numer)
d = str(denom)
fracs = []
if n!=d and n[1] == d[0]:
ELIF = 1
fn0 = float(n[0])
fd1 = float(d[1])
if disp:
print ('---------------------------------------\n'
'n == %s d == %s\n'
"float('%s'[0]) == %f float('%s'[1]) == %f"
% ( n,d,n,fn0,d,fd1 ) )
for i in range(2, numer+1):
if disp:
print ('i== %2d '
'%s./%2d==%10f %s./%2d==%10f %s' %
(i,n,i,float(n)/i,d,i,float(d)/i,
float(n)/i==fn0 and float(d)/i==fd1) )
if float(numer)/i==fn0 and float(denom)/i==fd1:
if disp:
print (' %s\n'
' - %s/%s returned by if section -' %
('- elif part is active -' if ELIF
else '- elif part is not active -',
n,d))
return n + "/" + d
if ELIF and d[1] != "0":
if Fraction( n[0] + '/' + d[1] ) \
== \
Fraction(numer, denom):
if disp:
print (' %s\n'
" Fraction('%s/%s') == %s\n"
" Fraction(%s, %s) == %s\n"
' - %s%s returned by elif section -' %
('- elif part is active -' if ELIF
else '- elif part is not active -',
n[0],d[1],Fraction( n[0] + '/' + d[1] ),
numer,denom,Fraction(numer, denom),n,d) )
return n + d
else:
if n+d=='4998':
if disp:
print (' - elif part is active -' if ELIF
else ' - elif part is not active -')
print ' - No convenient divisor found for 49 98 : returned by else section -'
return 'No convenient divisor found for 49 98'
显示
(skiped lines)
---------------------------------------
n == 26 d == 65
float('26'[0]) == 2.000000 float('65'[1]) == 5.000000
i== 2 26./ 2== 13.000000 65./ 2== 32.500000 False
i== 3 26./ 3== 8.666667 65./ 3== 21.666667 False
i== 4 26./ 4== 6.500000 65./ 4== 16.250000 False
i== 5 26./ 5== 5.200000 65./ 5== 13.000000 False
i== 6 26./ 6== 4.333333 65./ 6== 10.833333 False
i== 7 26./ 7== 3.714286 65./ 7== 9.285714 False
i== 8 26./ 8== 3.250000 65./ 8== 8.125000 False
i== 9 26./ 9== 2.888889 65./ 9== 7.222222 False
i== 10 26./10== 2.600000 65./10== 6.500000 False
i== 11 26./11== 2.363636 65./11== 5.909091 False
i== 12 26./12== 2.166667 65./12== 5.416667 False
i== 13 26./13== 2.000000 65./13== 5.000000 True
- elif part is active -
- 26/65 returned by if section -
frac == 26/65
---------------------------------------
n == 49 d == 98
float('49'[0]) == 4.000000 float('98'[1]) == 8.000000
i== 2 49./ 2== 24.500000 98./ 2== 49.000000 False
i== 3 49./ 3== 16.333333 98./ 3== 32.666667 False
i== 4 49./ 4== 12.250000 98./ 4== 24.500000 False
i== 5 49./ 5== 9.800000 98./ 5== 19.600000 False
i== 6 49./ 6== 8.166667 98./ 6== 16.333333 False
i== 7 49./ 7== 7.000000 98./ 7== 14.000000 False
i== 8 49./ 8== 6.125000 98./ 8== 12.250000 False
i== 9 49./ 9== 5.444444 98./ 9== 10.888889 False
i== 10 49./10== 4.900000 98./10== 9.800000 False
i== 11 49./11== 4.454545 98./11== 8.909091 False
i== 12 49./12== 4.083333 98./12== 8.166667 False
i== 13 49./13== 3.769231 98./13== 7.538462 False
i== 14 49./14== 3.500000 98./14== 7.000000 False
i== 15 49./15== 3.266667 98./15== 6.533333 False
i== 16 49./16== 3.062500 98./16== 6.125000 False
i== 17 49./17== 2.882353 98./17== 5.764706 False
i== 18 49./18== 2.722222 98./18== 5.444444 False
i== 19 49./19== 2.578947 98./19== 5.157895 False
i== 20 49./20== 2.450000 98./20== 4.900000 False
i== 21 49./21== 2.333333 98./21== 4.666667 False
i== 22 49./22== 2.227273 98./22== 4.454545 False
i== 23 49./23== 2.130435 98./23== 4.260870 False
i== 24 49./24== 2.041667 98./24== 4.083333 False
i== 25 49./25== 1.960000 98./25== 3.920000 False
i== 26 49./26== 1.884615 98./26== 3.769231 False
i== 27 49./27== 1.814815 98./27== 3.629630 False
i== 28 49./28== 1.750000 98./28== 3.500000 False
i== 29 49./29== 1.689655 98./29== 3.379310 False
i== 30 49./30== 1.633333 98./30== 3.266667 False
i== 31 49./31== 1.580645 98./31== 3.161290 False
i== 32 49./32== 1.531250 98./32== 3.062500 False
i== 33 49./33== 1.484848 98./33== 2.969697 False
i== 34 49./34== 1.441176 98./34== 2.882353 False
i== 35 49./35== 1.400000 98./35== 2.800000 False
i== 36 49./36== 1.361111 98./36== 2.722222 False
i== 37 49./37== 1.324324 98./37== 2.648649 False
i== 38 49./38== 1.289474 98./38== 2.578947 False
i== 39 49./39== 1.256410 98./39== 2.512821 False
i== 40 49./40== 1.225000 98./40== 2.450000 False
i== 41 49./41== 1.195122 98./41== 2.390244 False
i== 42 49./42== 1.166667 98./42== 2.333333 False
i== 43 49./43== 1.139535 98./43== 2.279070 False
i== 44 49./44== 1.113636 98./44== 2.227273 False
i== 45 49./45== 1.088889 98./45== 2.177778 False
i== 46 49./46== 1.065217 98./46== 2.130435 False
i== 47 49./47== 1.042553 98./47== 2.085106 False
i== 48 49./48== 1.020833 98./48== 2.041667 False
i== 49 49./49== 1.000000 98./49== 2.000000 False
- elif part is active -
Fraction('4/8') == 1/2
Fraction(49, 98) == 1/2
- 4998 returned by elif section -
frac == 4998
detected :
16/64
19/95
26/65
4998
nums == ['16', '19', '26', '49']
denoms == ['64', '95', '65', '98']
pro,duct == 387296 38729600
Fraction(pro, duct) == 1/100
The elapsed time is 2.45300006866 seconds.
但是,格式的差异表明,最后一个值是由另一个节( elif section
)返回的,而不是3个第一个值(由if section
返回)。
这值得澄清。
显示器显示不存在的值i
为其49./i
将是4
和98./i
将是8
:这意味着,没有理由认为n[0]==4
将是的除数n==49
和d[1]==8
的除数d==98
。
因此,问题的根源不是不可能用二进制表示形式精确地表示十进制值(导致难以在浮点算法中进行比较),而是算法问题。
仅当执行测试49./i==1.0 and 98.i==2.00
,才会导致返回由if section
格式化为3个第一个值的49/98
值。 因此,我认为以下代码具有正确的算法。 但是,无论给ELIF提供什么值,都不会执行elif section
和else section
。 那仅意味着if section
中的算法等同于带有Fraction
的elif section
的原理。
def curious(numer,denom,disp=None):
n = str(numer)
d = str(denom)
fracs = []
if n!=d and n[1] == d[0]:
ELIF = 1
fn0 = float(n[0])
fd1 = float(d[1])
GCD = gcd(fn0,fd1)
fn0DD = fn0/GCD
fd1DD = fd1/GCD
if disp:
print ('---------------------------------------\n'
'n == %s d == %s\n'
"float('%s'[0]) == %f float('%s'[1]) == %f"
% ( n,d,n,fn0,d,fd1 ) )
for i in range(2, numer+1):
if disp:
print ('i== %2d '
'%s./%2d==%10f %s./%2d==%10f %s' %
(i,n,i,float(n)/i,d,i,float(d)/i,
float(n)/i==fn0DD and float(d)/i==fd1DD) )
if float(numer)/i==fn0DD and float(denom)/i==fd1DD:
if disp:
print (' %s\n'
' - %s/%s returned by if section -' %
('- elif part is active -' if ELIF
else '- elif part is not active -',
n,d))
return n + "/" + d
if ELIF and d[1] != "0":
if Fraction( n[0] + '/' + d[1] ) \
== \
Fraction(numer, denom):
if disp:
print (' %s\n'
" Fraction('%s/%s') == %s\n"
" Fraction(%s, %s) == %s\n"
' - %s%s returned by elif section -' %
('- elif part is active -' if ELIF
else '- elif part is not active -',
n[0],d[1],Fraction( n[0] + '/' + d[1] ),
numer,denom,Fraction(numer, denom),n,d) )
return n + d
等待显示
(skipped lines)
i== 44 49./44== 1.113636 98./44== 2.227273 False
i== 45 49./45== 1.088889 98./45== 2.177778 False
i== 46 49./46== 1.065217 98./46== 2.130435 False
i== 47 49./47== 1.042553 98./47== 2.085106 False
i== 48 49./48== 1.020833 98./48== 2.041667 False
i== 49 49./49== 1.000000 98./49== 2.000000 True
- elif part is active -
- 49/98 returned by if section -
frac == 49/98
detected :
16/64
19/95
26/65
49/98
nums == ['16', '19', '26', '49']
denoms == ['64', '95', '65', '98']
pro,duct == 387296 38729600
Fraction(pro, duct) == 1/100
The elapsed time is 2.39100003242 seconds.
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.