Python:为什么我的 'if' 语句对数字的计算不正确?
Python: Why do my 'if' statements' evaluate numbers incorrectly?
代码如下:
from random import *
numStars = int(input("Number of stars: ").strip())
planetTypeDict = {'O':0, 'B':0, 'A':0, 'F':0, 'G':0, 'K':0, 'M':0}
for star in range (numStars):
planetTypeChanceNum = uniform (0, 100)
if planetTypeChanceNum < 76.45:
planetType = 'M'
planetTypeDict['M'] += 1
elif planetTypeChanceNum < 12.1:
planetType = 'K'
planetTypeDict['K'] += 1
elif planetTypeChanceNum < 7.6:
planetType = 'G'
planetTypeDict['G'] += 1
elif planetTypeChanceNum < 3:
planetType = 'F'
planetTypeDict['F'] += 1
elif planetTypeChanceNum < 0.6:
planetType = 'A'
planetTypeDict['A'] += 1
elif planetTypeChanceNum < 0.13:
planetType = 'B'
planetTypeDict['B'] += 1
elif planetTypeChanceNum < 0.0003:
planetType = 'O'
planetTypeDict['O'] += 1
print(planetTypeDict)
问题是代码输出大约有 75% 'M' 星,除此之外没有其他内容。例如,当我使用 1000 作为 numStars 的值时,我得到的结果是:
{'O': 241, 'B': 0, 'A': 0, 'F': 0, 'G': 0, 'K': 0, 'M': 759}
我已尽我所能来修复此错误,包括将逻辑更改为:
if planetTypeChanceNum > 100 - 'chance here':
# stuff
请帮忙!
您在滥用 elif
None 除了 M 之外的案例都会触发,因为一旦它们 'qualify' 在 M if 块中,它们就会跳过 elif。
要获得您想要的功能,您需要绑定您的 if 语句,而不是让它们单方面。
示例:
if 12.1 < planetTypeChanceNum < 76.45:
planetType = 'M'
planetTypeDict['M'] += 1
elif 7.6 < planetTypeChanceNum < 12.1:
planetType = 'K'
planetTypeDict['K'] += 1
有更有效的方法可以做到这一点,但我认为此时您只需要了解 if/elif 功能。
如果您使用 Python 3,请使用 random.choices
,如 Patrick Artner 所示。
否则,只需颠倒检查顺序即可:
if planetTypeChanceNum < 0.0003:
planetType = 'O'
elif planetTypeChanceNum < 0.13:
planetType = 'B'
elif planetTypeChanceNum < 0.6:
planetType = 'A'
elif planetTypeChanceNum < 3:
planetType = 'F'
elif planetTypeChanceNum < 7.6:
planetType = 'G'
elif planetTypeChanceNum < 12.1:
planetType = 'K'
elif planetTypeChanceNum < 76.45:
planetType = 'M'
planetTypeDict[planetType] += 1
如果第一次检查失败,planetTypeChanceNum
仍然可以小于0.13(暗示0.0003 <= planetTypeChanceNum
)。
但是,如果planetTypeChanceNum >= 76.45
,行星类型是什么?您缺少一个 else
子句,或者如果在那种情况下根本没有行星,则可能缺少一个初始 if
语句来尽早继续循环。
if planetTypeChanceNum < 0.0003:
planetType = 'O'
elif planetTypeChanceNum < 0.13:
planetType = 'B'
elif planetTypeChanceNum < 0.6:
planetType = 'A'
elif planetTypeChanceNum < 3:
planetType = 'F'
elif planetTypeChanceNum < 7.6:
planetType = 'G'
elif planetTypeChanceNum < 12.1:
planetType = 'K'
elif planetTypeChanceNum < 76.45:
planetType = 'M'
else:
planetType = ???
或
if planetType >= 76.45:
# No planet at all
continue
elif planetTypeChanceNum < 0.0003:
planetType = 'O'
elif planetTypeChanceNum < 0.13:
planetType = 'B'
elif planetTypeChanceNum < 0.6:
planetType = 'A'
elif planetTypeChanceNum < 3:
planetType = 'F'
elif planetTypeChanceNum < 7.6:
planetType = 'G'
elif planetTypeChanceNum < 12.1:
planetType = 'K'
elif planetTypeChanceNum < 76.45:
planetType = 'M'
这两个都将详尽地覆盖区间 [0, 100]。
这就是你想要的:
if planetTypeChanceNum < 0.0003:
planetType = 'O'
planetTypeDict['O'] += 1
elif planetTypeChanceNum < 0.13:
planetType = 'B'
planetTypeDict['B'] += 1
elif planetTypeChanceNum < 0.6:
planetType = 'A'
planetTypeDict['A'] += 1
elif planetTypeChanceNum < 3:
planetType = 'F'
planetTypeDict['F'] += 1
elif planetTypeChanceNum < 12.1:
planetType = 'K'
planetTypeDict['K'] += 1
elif planetTypeChanceNum < 76.45:
planetType = 'M'
planetTypeDict['M'] += 1
我想知道你是如何用你的原始代码得到任何'O'的...
您得不到结果,因为后面的测试永远不可能为真 - 前面的测试已经匹配:
if a < 10:
pass # this eats up a=0,1,2,3,4,...,9
elif a < 5:
pass # never gonna happen.
除此之外,您可以使用 random.choices()
为每个选择提供权重并使用 Counter
计算它们,从而使您的创作变得更加容易:
from random import choices
from collections import Counter
numStars = int(input("Number of stars: ").strip())
planetTypeDict = Counter({'O':0, 'B':0, 'A':0, 'F':0, 'G':0, 'K':0, 'M':0})
# https://docs.python.org/3/library/random.html#random.choices
# these weights are relative weights, meaning:
# M: 76.45 %
# K: 12.10 %
# G: 7.60 %
# F: 3.00 %
# A: 0.60 %
# B: 0.13 %
# O: 0.0003 %
# others - the rest of planet types (as the former do not add up to 100%)
types = [ "M","K","G","F","A","B","O", "other"]
w = [ 764500, 121000, 76000, 30000, 6000, 1300, 3,
1000000-sum( [764500, 121000, 76000, 30000, 6000, 1300, 3])]
planetTypeDict.update(choices(types,weights=w,k=numStars))
print(planetTypeDict.most_common())
输出(100 万颗星):
Number of stars: [('M', 763764), ('K', 121696), ('G', 75998), ('F', 29970),
('A', 6147), ('B', 1247), ('other', 1175), ('O', 3)]
独库:
@Chepner 指出你的权重可能已经累积了——考虑到你 if
的结构:
print(Counter(choices("OBAFGKMX", cum_weights=[0.0003 ,0.13 ,0.6 ,3 ,7.6 ,12.1,
76.45 ,100], k=1000000)))
导致:
Counter({'M': 643289, 'X': 235341, 'G': 45979, 'K': 45262, 'F': 24032, 'A': 4768, 'B': 1324, 'O': 5})
代码如下:
from random import *
numStars = int(input("Number of stars: ").strip())
planetTypeDict = {'O':0, 'B':0, 'A':0, 'F':0, 'G':0, 'K':0, 'M':0}
for star in range (numStars):
planetTypeChanceNum = uniform (0, 100)
if planetTypeChanceNum < 76.45:
planetType = 'M'
planetTypeDict['M'] += 1
elif planetTypeChanceNum < 12.1:
planetType = 'K'
planetTypeDict['K'] += 1
elif planetTypeChanceNum < 7.6:
planetType = 'G'
planetTypeDict['G'] += 1
elif planetTypeChanceNum < 3:
planetType = 'F'
planetTypeDict['F'] += 1
elif planetTypeChanceNum < 0.6:
planetType = 'A'
planetTypeDict['A'] += 1
elif planetTypeChanceNum < 0.13:
planetType = 'B'
planetTypeDict['B'] += 1
elif planetTypeChanceNum < 0.0003:
planetType = 'O'
planetTypeDict['O'] += 1
print(planetTypeDict)
问题是代码输出大约有 75% 'M' 星,除此之外没有其他内容。例如,当我使用 1000 作为 numStars 的值时,我得到的结果是:
{'O': 241, 'B': 0, 'A': 0, 'F': 0, 'G': 0, 'K': 0, 'M': 759}
我已尽我所能来修复此错误,包括将逻辑更改为:
if planetTypeChanceNum > 100 - 'chance here':
# stuff
请帮忙!
您在滥用 elif
None 除了 M 之外的案例都会触发,因为一旦它们 'qualify' 在 M if 块中,它们就会跳过 elif。
要获得您想要的功能,您需要绑定您的 if 语句,而不是让它们单方面。
示例:
if 12.1 < planetTypeChanceNum < 76.45:
planetType = 'M'
planetTypeDict['M'] += 1
elif 7.6 < planetTypeChanceNum < 12.1:
planetType = 'K'
planetTypeDict['K'] += 1
有更有效的方法可以做到这一点,但我认为此时您只需要了解 if/elif 功能。
如果您使用 Python 3,请使用 random.choices
,如 Patrick Artner 所示。
否则,只需颠倒检查顺序即可:
if planetTypeChanceNum < 0.0003:
planetType = 'O'
elif planetTypeChanceNum < 0.13:
planetType = 'B'
elif planetTypeChanceNum < 0.6:
planetType = 'A'
elif planetTypeChanceNum < 3:
planetType = 'F'
elif planetTypeChanceNum < 7.6:
planetType = 'G'
elif planetTypeChanceNum < 12.1:
planetType = 'K'
elif planetTypeChanceNum < 76.45:
planetType = 'M'
planetTypeDict[planetType] += 1
如果第一次检查失败,planetTypeChanceNum
仍然可以小于0.13(暗示0.0003 <= planetTypeChanceNum
)。
但是,如果planetTypeChanceNum >= 76.45
,行星类型是什么?您缺少一个 else
子句,或者如果在那种情况下根本没有行星,则可能缺少一个初始 if
语句来尽早继续循环。
if planetTypeChanceNum < 0.0003:
planetType = 'O'
elif planetTypeChanceNum < 0.13:
planetType = 'B'
elif planetTypeChanceNum < 0.6:
planetType = 'A'
elif planetTypeChanceNum < 3:
planetType = 'F'
elif planetTypeChanceNum < 7.6:
planetType = 'G'
elif planetTypeChanceNum < 12.1:
planetType = 'K'
elif planetTypeChanceNum < 76.45:
planetType = 'M'
else:
planetType = ???
或
if planetType >= 76.45:
# No planet at all
continue
elif planetTypeChanceNum < 0.0003:
planetType = 'O'
elif planetTypeChanceNum < 0.13:
planetType = 'B'
elif planetTypeChanceNum < 0.6:
planetType = 'A'
elif planetTypeChanceNum < 3:
planetType = 'F'
elif planetTypeChanceNum < 7.6:
planetType = 'G'
elif planetTypeChanceNum < 12.1:
planetType = 'K'
elif planetTypeChanceNum < 76.45:
planetType = 'M'
这两个都将详尽地覆盖区间 [0, 100]。
这就是你想要的:
if planetTypeChanceNum < 0.0003:
planetType = 'O'
planetTypeDict['O'] += 1
elif planetTypeChanceNum < 0.13:
planetType = 'B'
planetTypeDict['B'] += 1
elif planetTypeChanceNum < 0.6:
planetType = 'A'
planetTypeDict['A'] += 1
elif planetTypeChanceNum < 3:
planetType = 'F'
planetTypeDict['F'] += 1
elif planetTypeChanceNum < 12.1:
planetType = 'K'
planetTypeDict['K'] += 1
elif planetTypeChanceNum < 76.45:
planetType = 'M'
planetTypeDict['M'] += 1
我想知道你是如何用你的原始代码得到任何'O'的...
您得不到结果,因为后面的测试永远不可能为真 - 前面的测试已经匹配:
if a < 10:
pass # this eats up a=0,1,2,3,4,...,9
elif a < 5:
pass # never gonna happen.
除此之外,您可以使用 random.choices()
为每个选择提供权重并使用 Counter
计算它们,从而使您的创作变得更加容易:
from random import choices
from collections import Counter
numStars = int(input("Number of stars: ").strip())
planetTypeDict = Counter({'O':0, 'B':0, 'A':0, 'F':0, 'G':0, 'K':0, 'M':0})
# https://docs.python.org/3/library/random.html#random.choices
# these weights are relative weights, meaning:
# M: 76.45 %
# K: 12.10 %
# G: 7.60 %
# F: 3.00 %
# A: 0.60 %
# B: 0.13 %
# O: 0.0003 %
# others - the rest of planet types (as the former do not add up to 100%)
types = [ "M","K","G","F","A","B","O", "other"]
w = [ 764500, 121000, 76000, 30000, 6000, 1300, 3,
1000000-sum( [764500, 121000, 76000, 30000, 6000, 1300, 3])]
planetTypeDict.update(choices(types,weights=w,k=numStars))
print(planetTypeDict.most_common())
输出(100 万颗星):
Number of stars: [('M', 763764), ('K', 121696), ('G', 75998), ('F', 29970),
('A', 6147), ('B', 1247), ('other', 1175), ('O', 3)]
独库:
@Chepner 指出你的权重可能已经累积了——考虑到你 if
的结构:
print(Counter(choices("OBAFGKMX", cum_weights=[0.0003 ,0.13 ,0.6 ,3 ,7.6 ,12.1,
76.45 ,100], k=1000000)))
导致:
Counter({'M': 643289, 'X': 235341, 'G': 45979, 'K': 45262, 'F': 24032, 'A': 4768, 'B': 1324, 'O': 5})