在if-else语句中使用范围(..)

时间:2012-08-27 10:24:24

标签: python

python 2.7

是否可以这样做:

print "Enter a number between 1 and 10:"
number = raw_input("> ")

if number in range(1, 5):
    print "You entered a number in the range of 1 to 5"
elif number in range(6, 10):
    print "You entered a number in the range of 6 to 10"
else:
    print "Your number wasn't in the correct range"

我发现如果我把一个数字放在1到10之间,它总是属于else语句。

这是否在if-else语句中使用in range?

非常感谢,

5 个答案:

答案 0 :(得分:6)

这是因为输入数据是字符串。所以它流向了其他地方。将它转换为整数然后一切都会好的。

>>> number = raw_input("> ")
>>> type(number)
<type 'str'>
int(number) converts to <type 'int'>

请使用:

if int(number) in range(1, 6):
    print "You entered a number in the range of 1 to 5"
elif int(number) in range(6, 11):
    print "You entered a number in the range of 6 to 10"
else:
    print "Your number wasn't in the correct range"

答案 1 :(得分:5)

>>> number = raw_input()
3
>>> type(number)
<type 'str'>
>>> "3" in range(1,5)
False


number = int(raw_input())

答案 2 :(得分:3)

在检查之前,您应该先将输入(字符串)转换为数字。您还应该使用if 1 < number <= 5:,无需创建列表来检查数字是否在范围内。

答案 3 :(得分:1)

为了完整起见,in运算符可以用作测试属性成员资格的布尔运算符。因此可以在if..else语句中使用(请参阅下面的完整文档摘录)。

使用in运算符时(例如obj in container),解释程序首先会查看container是否有__contains__方法。如果没有,但如果container定义__iter__方法,则python将迭代对象中包含的所有值并测试相等性,即它基本上会执行类似

的操作
for value in container:
    if value == obj:
        return True
return False

最后,如果两个方法都没有定义,则解释器会查找__getitem__方法来迭代容器,并仍然会使用obj测试任何值的相等性。 您也可以查看the comparison operator documentation

现在,在您的情况下,range([start], stop[, step])函数[documentation]实际上会返回一个列表(请注意,此列表保留最后一个元素,因此range(1, 5) == [1, 2, 3, 4]) ,它定义了__contains__方法:

>>> type(range(1, 10))
list
>>> hasattr(list, '__contains__')
True
>>> 4 in range(1, 10)
True

所以这完全有权写x in range(1, 10)。正如其他答案所指出的,您的问题实际上是通过将输入数据转换为整数来解决的类型问题(因为"3" == 3为False)。 但是,如果您只打算测试输入值是否正确有限,我肯定会建议您使用比较运算符

>>> if 1 <= x < 10:
...     print 'ok'
... else:
...     print 'ko'

因为它看起来更易读你没有构建一个过时的列表,所以你可以减少你的内存占用。

请注意,为了避免列表的隐式构造,您可以使用返回迭代器而不是列表的xrange函数,在这种情况下,由于值被延迟评估,xrange会没有定义__contains__方法,但它定义了__iter__方法,所以一切都会正常工作!

>>> type(xrange(1, 10))
xrange
>>> hasattr(xrange, '__contains__')
False
>>> hasattr(xrange, '__iter__')
True
>>> 4 in xrange(1, 10)
True

最后,这里是关于in operator

的python文档的摘录
  

运营商是否参与集合成员资格测试。如果x是集合s的成员,则x in s的计算结果为true,否则为false。 x不在s中返回s中x的否定。集合成员资格测试传统上一直与序列绑定;如果集合是序列并且包含与该对象相等的元素,则对象是集合的成员。但是,许多其他对象类型支持成员资格测试而不是序列是有意义的。特别是,词典(用于键)和集合支持成员资格测试。

     

对于列表和元组类型,当且仅当存在索引i使得x == y [i]为真时,y中的x才为真。

     

对于Unicode和字符串类型,当且仅当x是y的子字符串时,y中的x才为真。等效测试是y.find(x)!= -1。注意,x和y不必是相同的类型;因此,'u'ab'in'abc'将返回True。空字符串始终被视为任何其他字符串的子字符串,因此“abc”中的“”将返回True。

     

版本2.3中更改:以前,x必须是长度为1的字符串。

     

对于定义__contains__()方法的用户定义类,当且仅当y。__contains__(x)为真时,y中的x才为真。

     

对于未定义__contains__()但定义__iter__()的用户定义类,如果在迭代y时生成某些值为x == z的值,则y中的x为真。如果在迭代期间引发异常,那就好像是在异常中引发异常。

     

最后,尝试了旧式迭代协议:如果一个类定义__getitem__(),当y并且只有当存在非负整数索引i时,x中的x才为真,即x == y [i],并且所有较低的整数索引都不会引发IndexError异常。 (如果引发任何其他异常,就好像在异常中引发异常)。

     

不在的运算符被定义为具有in的反向真值。

     

运算符是和不测试对象标识:当且仅当x和y是同一个对象时,x是y才为真。 x不是y产生反向真值。 [7]

答案 4 :(得分:1)

另一种可能的解决方案是在开头使用int:

number = int(raw_input("> "))