Xác định xem số nguyên có nằm giữa hai số nguyên khác không?


398

Làm cách nào để xác định xem một số nguyên đã cho có nằm giữa hai số nguyên khác không (ví dụ: lớn hơn / bằng 10000và nhỏ hơn / bằng 30000)?

Tôi đang sử dụng 2.3 IDLE và những gì tôi đã thử cho đến nay không hoạt động:

if number >= 10000 and number >= 30000:
    print ("you have to pay 5% taxes")

20
Kiểm tra các toán tử boolean của bạn, tất nhiên một số sẽ lớn hơn 10000 nếu nó lớn hơn 30000. Hãy nhìn vào các chi tiết nhỏ và bạn sẽ bắt được nhiều lỗi hơn.
Kaili


6
Xin thay đổi> = 30000 thành <= 30000
Badiboy

Câu trả lời:


1046
if 10000 <= number <= 30000:
    pass

208
Python rất đẹp :). Và để được dự phòng: điều này được gọi là "so sánh khoảng."
Matt Montag

Sự khác biệt tốc độ giữa điều này và if number in range(10000, 30001)như được đề xuất bởi giải pháp khác là gì? Ngoài ra, nó nhanh hơn hay chậm hơn khi sử dụng setthay vì range?
Sung Cho

15
@MikeC Với so sánh khoảng numberđầu tiên được so sánh với 10000. Nếu nó nhỏ hơn 10000biểu thức ngay lập tức bị ngắn mạch và so sánh thứ hai không được kiểm tra. Sự phức tạp là O(1). in range(0, n)thay vào đó tạo ra toàn bộ chuỗi số và sau đó lặp qua nó. Sự phức tạp là O(n). Sự phức tạp in set(range(0, n))vẫn còn O(n)bởi vì việc xây dựng một tập hợp có độ phức tạp về thời gian của O(n) ics.uci.edu/~pattis/ICS-33/lectures/complexitypython.txt
Paolo Moretti

5
@MikeC Hãy thử chạy trong vỏ của bạn:> python -m timeit '10000 <= 10 <= 30000' > python -m timeit '10 in range(10000, 30001)' > python -m timeit '10 in set(range(10000, 30001))'
Paolo Moretti

3
trông giống như trong python3.5.2, phạm vi chậm hơn ~ 10 lần so với câu lệnh if, với hằng số tốc độ liên quan đến giá trị kiểm tra phạm vi ... do đó rất có thể là sự khác biệt do chi phí hoạt động.
amohr

78
>>> r = range(1, 4)
>>> 1 in r
True
>>> 2 in r
True
>>> 3 in r
True
>>> 4 in r
False
>>> 5 in r
False
>>> 0 in r
False

4
Wow tôi luôn nghĩ range(hoặc xrangetrong python2) trả về một trình tạo do đó bạn không thể liên tục kiểm tra nó.
ngày

24
Điều quan trọng của nó để ghi nhớ đó 4 in range(1,4)là Sai. Vì vậy, sử dụng tốt hơn 1 >= r <= 4vì nó tránh được các lỗi có thể xảy ra bởi những người mới đến
tripplet

50
1.5 in rcho False, ngay cả trong 3,4. Câu trả lời này chỉ tốt cho số nguyên.
jpmc26

9
@tripplet, bạn đã mắc lỗi tương tự như OP!, Đáng lẽ ra là1 <= r <= 4
John La Rooy

8
(1.) hiệu suất kém (như những người khác đã chỉ ra cú pháp này có vẻ tốt nhưng có thể mất nhiều thời gian để thực thi vì đó là hoạt động O (n) so với if a <= x <= b...) (2.) không hoạt động đối với floatcác loại (3 .) kiểm tra phạm vi không bao gồm ... vì vậy nhiều nhà phát triển có thể đưa ra các lỗi vì họ mong đợi phạm vi bao gồm
Trevor Boyd Smith

52

Toán tử của bạn không chính xác. Nên if number >= 10000 and number <= 30000:. Ngoài ra, Python có một tốc ký cho loại điều này , if 10000 <= number <= 30000:.


3
... loại điều này thường được gọi là so sánh xích .
Sói

30

Đoạn mã của bạn,

if number >= 10000 and number >= 30000:
    print ("you have to pay 5% taxes")

thực sự kiểm tra xem số có lớn hơn cả 10000 và 30000 không.

Giả sử bạn muốn kiểm tra xem số đó có nằm trong phạm vi 10000 - 30000 hay không, bạn có thể sử dụng phép so sánh khoảng Python:

if 10000 <= number <= 30000:
    print ("you have to pay 5% taxes")

Tính năng Python này được mô tả thêm trong tài liệu Python .



8

Vấn đề với việc so sánh là chúng có thể khó gỡ lỗi khi bạn đặt một >=nơi cần có<=

#                             v---------- should be <
if number >= 10000 and number >= 30000:
    print ("you have to pay 5% taxes")

Python cho phép bạn viết những gì bạn muốn nói

if number in xrange(10000, 30001): # ok you have to remember 30000 + 1 here :)

Trong Python3, bạn cần sử dụng rangethay vì xrange.

chỉnh sửa: Mọi người dường như quan tâm nhiều hơn đến nhãn hiệu microbench và cách hoạt động của chuỗi mát mẻ. Câu trả lời của tôi là về lập trình phòng thủ (ít tấn công bề mặt cho lỗi).

Do khiếu nại trong các nhận xét, tôi đã thêm điểm chuẩn vi mô ở đây cho Python3.5.2

$ python3.5 -m timeit "5 in range(10000, 30000)"
1000000 loops, best of 3: 0.266 usec per loop
$ python3.5 -m timeit "10000 <= 5 < 30000"
10000000 loops, best of 3: 0.0327 usec per loop

Nếu bạn lo lắng về hiệu suất, bạn có thể tính toán phạm vi một lần

$ python3.5 -m timeit -s "R=range(10000, 30000)" "5 in R"
10000000 loops, best of 3: 0.0551 usec per loop

2
Thật không may, xrange không được dùng trong Python 3.
apraetor

1
@apraetor, có sử dụng range(10000, 30001)trong Python3. Nó không tạo ra một danh sách
John La Rooy

3
@JBChouinard, bạn hoàn toàn không chính xác. xrangetrong Python2 hoặc rangetrong Python3 có các bài kiểm tra thành viên. Hãy tự thử nếu bạn không tin. <=chỉ hiệu quả hơn vì nó không tạo ra một đối tượng phạm vi. Cả hai cách như O (1). Vấn đề là OP đã cố gắng làm theo cách của bạn và kết thúc với một lỗi . Mã nhanh mà sai thì tệ hơn.
John La Rooy

2
trên i5, (i) python 3.5:% timeit 5 trong phạm vi (10000, 30000) 1000 vòng, tốt nhất là 3: 451 Lỗi mỗi vòng. % timeit 10000 <= 5 <= 30000 10000000 vòng, tốt nhất là 3: 59,4 ns mỗi vòng. đó là một yếu tố của hơn 7000
tback

1
@tback, Nếu có cơ hội thì nó chậm hơn 7000 lần, tôi sẽ không đề xuất điều đó. Có lẽ bạn có thể thử chạy thử nghiệm một lần nữa.
John La Rooy

8

Xác định phạm vi giữa các số:

r = range(1,10)

Sau đó sử dụng nó:

if num in r:
    print("All right!")

3
rangekhông tính 10 giá trị cuối cùng trong trường hợp của bạn. range(1,11)là chính xác, nếu bạn cần so sánh giữa 1 và 10
ikbel benabdessamad

6

hai cách để so sánh ba số nguyên và kiểm tra xem b có nằm giữa ac không :

if a < b < c:
    pass

if a < b and b < c:
    pass

Cái thứ nhất có vẻ dễ đọc hơn, nhưng cái thứ hai chạy nhanh hơn .

Hãy so sánh bằng cách sử dụng dis.dis :

    >>> dis.dis('a < b and b < c')
  1           0 LOAD_NAME                0 (a)
              2 LOAD_NAME                1 (b)
              4 COMPARE_OP               0 (<)
              6 JUMP_IF_FALSE_OR_POP    14
              8 LOAD_NAME                1 (b)
             10 LOAD_NAME                2 (c)
             12 COMPARE_OP               0 (<)
        >>   14 RETURN_VALUE
>>> dis.dis('a < b < c')
  1           0 LOAD_NAME                0 (a)
              2 LOAD_NAME                1 (b)
              4 DUP_TOP
              6 ROT_THREE
              8 COMPARE_OP               0 (<)
             10 JUMP_IF_FALSE_OR_POP    18
             12 LOAD_NAME                2 (c)
             14 COMPARE_OP               0 (<)
             16 RETURN_VALUE
        >>   18 ROT_TWO
             20 POP_TOP
             22 RETURN_VALUE
>>>

và sử dụng timeit :

~$ python3 -m timeit "1 < 2 and 2 < 3"
10000000 loops, best of 3: 0.0366 usec per loop

~$ python3 -m timeit "1 < 2 < 3"
10000000 loops, best of 3: 0.0396 usec per loop

Ngoài ra, bạn có thể sử dụng phạm vi , như được đề xuất trước đây, tuy nhiên nó chậm hơn nhiều.


0

Giả sử có 3 số nguyên không âm: a, b, và c. Về mặt toán học, nếu chúng ta muốn xác định xem ccó nằm giữa ab, bao gồm, người ta có thể sử dụng công thức này:

(c - a) * (b - c)> = 0

hoặc bằng Python:

> print((c - a) * (b - c) >= 0)
True

Điều này sai, lấy ví dụ đơn giản a = 1, b = 2, c = 3 ba = 1 ca = 2 (ba) * (ca) = 1 * 2> = 0 True => 3 nằm trong khoảng từ 1 đến 2
Richard Ardelean

Xin lỗi vì sai lầm của tôi. Tôi đã chỉnh sửa câu trả lời của mình @RichardArdelean.
Anastasiya-Romanova

0

Bạn muốn đầu ra in câu lệnh đã cho khi và chỉ khi số đó nằm trong khoảng từ 10.000 đến 30.000.

Mã phải được;

if number >= 10000 and number <= 30000:
    print("you have to pay 5% taxes")

3
Câu trả lời này đã được đề xuất. Câu trả lời của bạn thêm gì vào câu hỏi?
Jaideep Shekhar

0

Điều kiện nên là,

if number == 10000 and number <= 30000:
     print("5% tax payable")

Lý do sử dụng number == 10000là nếu giá trị của số là 50000 và nếu chúng tôi sử dụng number >= 10000thì điều kiện sẽ vượt qua, đó không phải là điều bạn muốn.


Điều này sẽ thất bại cho 10001, ví dụ, mặc dù. Anh ta muốn số từ 10000 đến 30000. Điều kiện của bạn sẽ chỉ hoạt động cho số == 10000.
guerreiro
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.