Tamsayının Diğer İki Tam Sayı Arasında Olup Olmadığını Belirleme?


398

Belirli bir tamsayının diğer iki tamsayı arasında olup olmadığını nasıl belirleyebilirim (örneğin büyük / eşittir 10000/ eşittir / eşittir / eşittir 30000)?

2.3 IDLE kullanıyorum ve şimdiye kadar denediğim şey çalışmıyor:

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

20
Boolean operatörlerinizi kontrol edin, elbette bir sayı 30000'den büyükse 10000'den büyük olacaktır. Küçük detaylara bakın ve çok daha fazla hata yakalayacaksınız.
Kaili


6
Pls> = 30000 olarak değiştirildi <= 30000
Badiboy

Yanıtlar:


1045
if 10000 <= number <= 30000:
    pass

208
Python çok güzel :). Ve gereksiz olmak: buna "aralık karşılaştırması" denir.
Matt Montag

Bu ve if number in range(10000, 30001)diğer çözümlerin önerdiği hız farkı nedir ? Ayrıca, setyerine kullanırken daha hızlı veya daha yavaş rangemı?
Sung Cho

15
@MikeC Aralık karşılaştırması numberilk olarak karşılaştırılır 10000. İfadeden küçükse 10000hemen kısa devre yapar ve ikinci karşılaştırma kontrol edilmez. Karmaşıklık O(1). in range(0, n)bunun yerine tüm sayı dizisini oluşturur ve ardından bu sayıyı yineler. Karmaşıklık O(n). Karmaşıklığı in set(range(0, n))hala O(n)bir set oluşturmanın O(n) ics.uci.edu/~pattis/ICS-33/lectures/complexitypython.txt
Paolo Moretti

5
@MikeC Kabuğunuzda koşmaya çalışı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
python3.5.2'de göründüğü gibi, aralık, if denetiminden ~ 10x daha yavaştır, aralık kontrol değeri ile ilgili hız sabiti ile ... bu nedenle işlev yükü nedeniyle büyük olasılıkla fark.
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
Vay be ben her zaman düşündüm range(veya xrangepython2) bir jeneratör döndürür böylece tekrar tekrar test edemezsiniz.
yegle

24
4 in range(1,4)Yanlış olduğunu akılda tutmak önemlidir . 1 >= r <= 4Yeni gelenlerin olası hataları önlediği için daha iyi kullanın
tripplet

50
1.5 in rFalse3.4'te bile verir . Bu cevap sadece tamsayılar için iyidir.
jpmc26

9
@tripplet, OP ile aynı hatayı yaptınız!, olmalı1 <= r <= 4
John La Rooy

8
(1.) kötü performans (diğerlerinin işaret ettiği gibi bu sözdiziminin iyi göründüğü, ancak O (n) işlemleri vs if a <= x <= b... olduğu için yürütülmesi uzun sürebilir .) (2.) floattürler için çalışmıyor (3) .) menzil testi kapsayıcı değildir ... pek çok geliştirici, kapsayıcı menzil bekledikleri için hatalar sunabilir
Trevor Boyd Smith

52

Operatörünüz yanlış. Olmalı if number >= 10000 and number <= 30000:. Ayrıca, Python'un bu tür şeyler için bir kestirme yolu vardır if 10000 <= number <= 30000:.


3
... bu tür şeylere genellikle zincirleme karşılaştırma denir .
Kurt

30

Kod snippet'iniz,

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

sayının hem 10000 hem de 30000'den büyük olup olmadığını gerçekten kontrol eder.

Sayının 10000 - 30000 aralığında olduğunu kontrol etmek istediğinizi varsayarsak, Python aralık karşılaştırmasını kullanabilirsiniz:

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

Bu Python özelliği Python belgelerinde daha ayrıntılı olarak açıklanmaktadır .


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

8

Karşılaştırmalardaki sorun, bir >=yere yerleştirdiğinizde hata ayıklamanın zor olabileceğidir.<=

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

Python kelimelerle ne demek istediğinizi yazmanıza izin verir

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

Python3'te rangebunun yerine kullanmanız gerekir xrange.

edit: İnsanlar daha mikrobench işaretleri ve ne kadar havalı zincirleme işlemleri ile ilgili gibi görünüyor. Cevabım savunma (hatalar için daha az saldırı yüzeyi) programlama ile ilgilidir.

Yorumlardaki bir iddia sonucunda, Python3.5.2 için mikro karşılaştırmalı değerlendirmeyi buraya ekledim

$ 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

Performans konusunda endişeleriniz varsa, aralığı bir kez hesaplayabilirsiniz

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

2
xrange maalesef Python 3'te kullanımdan kaldırıldı.
apraetor

1
@apraetor, evet Python3'te kullanın range(10000, 30001). Liste oluşturmuyor
John La Rooy

3
@JBChouinard, kesinlikle yanlışsın. xrangePython2 veya rangePython3'te üyelik testleri vardır. Eğer inanmıyorsanız kendiniz deneyin. <=yalnızca daha verimlidir çünkü bir aralık nesnesi oluşturmaz. Her iki şekilde O (1). Nokta OP edilir edildi Senin yöntemini yapmaya çalışıyor ve bir hata ile sona erdi . Yanlış olan hızlı kod daha kötüdür.
John La Rooy

2
bir i5 üzerinde, (i) python 3.5: (10000, 30000) 1000 döngüde% timeit 5, döngü başına en iyi 3: 451 µs. % timeit 10000 <= 5 <= 30000 10000000 döngü, döngü başına en iyi 3: 59,4 ns. bu 7000'in üzerinde bir faktör
tback

1
@tback, 7000 kat daha yavaş olma şansı olsaydı, bunu öneremezdim. Belki de testi tekrar yapmayı deneyebilirsiniz.
John La Rooy

8

Sayılar arasındaki aralığı tanımlayın:

r = range(1,10)

Sonra kullanın:

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

3
rangedavanızdaki son değeri 10 saymaz . range(1,11)1 ile 10 arasında karşılaştırmanız gerekiyorsa doğru
ikbel benabdessamad

6

Üç tamsayıyı karşılaştırmanın ve b'nin a ve c arasında olup olmadığını kontrol etmenin iki yolu vardır :

if a < b < c:
    pass

ve

if a < b and b < c:
    pass

Birincisi daha okunabilir gibi görünüyor, ancak ikincisi daha hızlı çalışıyor .

Dis.dis kullanarak karşılaştırma yapalım :

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

ve timeit kullanarak :

~$ 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

Ayrıca, daha önce önerildiği gibi aralığı kullanabilirsiniz , ancak çok daha yavaştır.


0

Orada varsayalım 3 negatif olmayan tam sayılardır: a, b, ve c. Matematiksel olarak konuşursak, eğer carasında ave dahilinde olup olmadığını belirlemek istiyorsak , bbu formülü kullanabiliriz:

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

veya Python'da:

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

Bu yanlış, a = 1, b = 2, c = 3 ba = 1 ca = 2 (ba) * (ca) = 1 * 2> = 0 Doğru => 3 1 ile 2 arasında
Richard Ardelean

Yaptığım hata için özür dilerim. Cevabımı @RichardArdelean düzenledim.
Anastasiya-Romanova 秀

0

Çıktının, yalnızca sayı 10.000 ile 30.000 arasında olması durumunda verilen ifadeyi yazdırmasını istersiniz.

Kod;

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

3
Bu cevap zaten önerildi. Cevabınız soruya ne katıyor?
Jaideep Shekhar

0

Durum şu olmalı,

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

Bunun nedeni, number == 10000numaranın değeri 50000 ise ve eğer number >= 10000koşulu kullanırsak , istediğiniz şey değildir.


Örneğin, bu 10001 için başarısız olacaktır. 10000 ve 30000 arasında sayılar istiyor. Durumunuz sadece == 10000 için çalışacaktır.
guerreiro
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.