Python bölümü


133

-100'den 0'dan 10-100'e kadar bir sayı kümesini normalleştirmeye çalışıyordum ve sadece hiç değişken olmasa bile bunun beklediğim şekilde değerlendirilmediğini fark etmekte zorlanıyordum:

>>> (20-10) / (100-10)
0

Float bölümü de çalışmıyor:

>>> float((20-10) / (100-10))
0.0

Bölümün her iki tarafı da bir şamandıraya atılırsa, çalışacaktır:

>>> (20-10) / float((100-10))
0.1111111111111111

İlk örnekteki her bir taraf bir int olarak değerlendiriliyor, bu da son cevabın bir int'e dönüştürüleceği anlamına geliyor. 0.111, 0.5'ten küçük olduğu için 0'a yuvarlar. Bence şeffaf değil, ama sanırım böyle.

Açıklaması nedir?



3
Adam, açıklamanı hala beğenmedim. İlk örnek, basitçe 0 döndüren tamsayı bölmesidir. İkinci örnek, istediğiniz efekt için yanlış olarak parantez içine alınmıştır.
Başkan James K. Polk

@GregS İlk örnek problemdi. İkinci örnek açıklayıcıdır ve ilk sorudan sonra yazılmıştır. Aşağıdaki tüm cevaplar sorunu çok iyi açıklıyor, özellikle @ KennyTM 'ler. Orijinal problemimin sadece Python 2.x ile ilgili bir sorun olduğunu not etmek önemlidir, 3. değil. Davranışın böyle değişeceği biraz endişe verici ama şimdi bildiğim kadarıyla, gelecekteki içe aktarma bölümünden kullanacağım ve 3'ü kullanacağım. .x davranışı. Şerefe.
Adam Nelson

1
Adam, lütfen son EDIT'inizi düzeltin. Sağ tarafın kendine has hiçbir şeyi yok; bir bölümün kayan olması için, pay veya paydanın (veya her ikisinin) yüzen olması gerekir. Dokümanlarda sağ tarafın kayması gerektiğini okuduğunuzu düşünüyorsanız, dokümantasyon ya kötü bir şekilde ifade edilmiş ve düzeltilmelidir ya da yanlış anladınız. Bir örnek gördünüz mü ve sonra ondan bir kural çıkarabildiniz mi?
tzot

Yanıtlar:


246

Tam sayı bölümlerinin kayan nokta sayısı olmak yerine kesileceği Python 2.x kullanıyorsunuz.

>>> 1 / 2
0

Bunlardan birini a yapmalısınız float:

>>> float(10 - 20) / (100 - 10)
-0.1111111111111111

veya Python 3.x'in her zaman bir float döndüren davranışını benimsemeye from __future__ import divisionyönelik güçler /.

>>> from __future__ import division
>>> (10 - 20) / (100 - 10)
-0.1111111111111111

10
Eğer from __future__ import divisionkullanırsanız, iki eğik çizgi kullanarak eski C-stili bölme davranışını elde edebilirsiniz (örneğin 1 // 20 ile sonuçlanır). Bakınız Pep 238 Bölüm Operatörünü Değiştiriyor
Kullanıcı

1
@User'dan içe aktarmaya gerek yok __future__. Hem Python 2 hem de 3 varsayılan olarak //ifade eder __floordiv__().
Casimir

21

Sen ediyoruz Python size bir tamsayı geri veriyor böylece de Tamsayılar koyarak :

>>> 10 / 90
0

Bunu daha sonra bir kayan noktaya atarsanız, yuvarlama zaten yapılmış olacaktır, başka bir deyişle, 0 tamsayı her zaman 0 float olacaktır.

Bölmenin her iki tarafında yüzer kullanırsanız, Python size beklediğiniz cevabı verecektir.

>>> 10 / 90.0
0.1111111111111111

Yani senin durumunda:

>>> float(20-10) / (100-10)
0.1111111111111111
>>> (20-10) / float(100-10)
0.1111111111111111

11

Bölmeyi yapmadan ÖNCE onu bir şamandıra olarak değiştirmeniz gerekir. Yani:

float(20 - 10) / (100 - 10)

4
@Adam Nelson: Benim için doğru çalışıyor. Parantezlerinizi kontrol edin.
Fred Larson

Aslında yanılıyorum - ancak belgelere baktıktan sonra, önce doğru tarafı atmalıyım.
Adam Nelson

10
@Adam: Önce hangi tarafın olduğu önemli değil.
kennytm

11

Python 2.7'de, /girişler tamsayı ise operatör bir tamsayı bölümüdür:

>>>20/15
1

>>>20.0/15.0
1.33333333333

>>>20.0/15
1.33333333333

Python 3.3'te, /girişler tamsayı olsa bile operatör bir kayan bölümdür.

>>> 20/15
1.33333333333

>>>20.0/15
1.33333333333

Python 3'te tamsayı bölme için, // operatörü .

//Operatör iki Python 2.7 ve Python 3.3 arasında bir tam sayı bölümü operatördür.

Python 2.7 ve Python 3.3'te:

>>>20//15
1

Şimdi karşılaştırmaya bakın

>>>a = 7.0/4.0
>>>b = 7/4
>>>print a == b

Yukarıdaki program için çıktı Python 2.7'de False ve Python 3.3'te True olacaktır.

Python 2.7'de a = 1.75 ve b = 1.

Python 3.3'te a = 1.75 ve b = 1.75, çünkü /bir float bölümüdür.


8

Kullandığınız python sürümüyle ilgisi var. Temelde C davranışını benimser: iki tamsayıyı bölerseniz, sonuçlar bir tam sayıya yuvarlanır. Ayrıca Python'un işlemleri soldan sağa yaptığını ve bu da döküm yazarken rol oynadığını unutmayın.

Örnek: Bu, aritmetik işlemler yaparken her zaman aklıma gelen bir soru olduğu için (float'a dönüştürmeli miyim ve hangi sayı), bu yönden bir örnek sunulmuştur:

>>> a = 1/2/3/4/5/4/3
>>> a
0

Tam sayıları böldüğümüzde, şaşırtıcı olmayan bir şekilde daha düşük yuvarlanır.

>>> a = 1/2/3/4/5/4/float(3)
>>> a
0.0

Float için son tamsayıyı yazarsak, yine de sıfır elde ederiz, çünkü sayımız float ile bölündüğünde, tamsayı bölümü nedeniyle zaten 0 olmuştur.

>>> a = 1/2/3/float(4)/5/4/3
>>> a
0.0

Yukarıdaki senaryo ile aynı, ancak şamandıra tipini sol tarafa biraz daha yaklaştırmak.

>>> a = float(1)/2/3/4/5/4/3
>>> a
0.0006944444444444445

Son olarak, float için ilk tamsayıyı yazdığımızda, sonuç istenen sayıdır, çünkü ilk bölümden, yani en soldaki, float kullanırız.

Ekstra 1: Aritmetik değerlendirmeyi geliştirmek için buna cevap vermeye çalışıyorsanız, kontrol etmelisiniz bu

Ekstra 2: Lütfen aşağıdaki senaryoya dikkat edin:

>>> a = float(1/2/3/4/5/4/3)
>>> a
0.0

4

Bir '.' Yerleştirerek bir kayan nokta belirleme sayıdan sonra, sayı da varsayılan olarak yüzer.

>>> 1 / 2
0

>>> 1. / 2.
0.5

2

Bunlardan en az birini yüzer yapın, o zaman bu tamsayı değil, kayan bölme olacaktır:

>>> (20.0-10) / (100-10)
0.1111111111111111

Sonucu kayan noktaya dönüştürmek çok geç.


1

Python'da cv2bölme hesaplaması güncellenmedi. bu nedenle, from __future__ import division programın ilk satırına eklemelisiniz .


0

Her iki durumda da, tamsayı bölümü. 10/90 = 0. İkinci durumda, sadece bir float'a 0 atıyorsunuz.

"/" İşlenenlerinden birini kayan nokta olarak yayınlamayı deneyin:

float(20-10) / (100-10)

0

İkinci örneğinizde bölünme zaten gerçekleştikten sonra float için döküm yapıyorsunuz. Bunu dene:

float(20-10) / float(100-10)

0

Orijinal posterin sonuçta rasyonel sayılardan hoşlanabileceğinden kimsenin bahsetmemesine biraz şaşırdım . Bununla ilgileniyorsanız, Python tabanlı program Sage arkanızda . (Şu anda hala Python 2.x tabanlı, ancak 3.x devam ediyor.)

sage: (20-10) / (100-10)
1/9

Bu herkes için bir çözüm değil, çünkü bazı hazırlıklar yapıyor, bu yüzden bu sayılar ints değil , Sage Integersınıfı öğeler. Yine de Python ekosisteminin bir parçası olarak bahsetmeye değer.


0

Şahsen ben 1. *en başında a eklemeyi tercih ettim . Yani ifade şuna benzer:

1. * (20-10) / (100-10)

Her zaman aşağıdaki gibi bir formül için bir bölme yaptığım gibi:

accuracy = 1. * (len(y_val) - sum(y_val)) / len(y_val)

yüzden sadece eklemek mümkün değildir .0gibi 20.0. Ve benim durumumda, bir ile sarmak float()okunabilirliği biraz kaybedebilir.

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.