Python'da% 'nın sonucu nedir?


241

%Hesaplamada ne yapar ? Ne yaptığını anlayamıyorum.

Örneğin, hesaplama yüzdesini hesaplıyor 4 % 2mu? Görünüşe göre 0'a eşit. Nasıl?

Yanıtlar:


304

% (Modulo) operatörü, ilk argümanın ikinciye bölünmesinden kalanını verir. Sayısal bağımsız değişkenler önce ortak bir türe dönüştürülür. Sıfır sağ argümanı ZeroDivisionError istisnasını yükseltir. Değişkenler kayan nokta sayıları olabilir, örn.,% 3.14 0.7, 0.34'e eşittir (3.14, 4 * 0.7 + 0.34'e eşit olduğundan.) Modulo operatörü her zaman ikinci işleneni (veya sıfır) ile aynı işarete sahip bir sonuç verir; sonucun mutlak değeri, ikinci işlenenin mutlak değerinden kesinlikle daha küçüktür [2].

Alındığı http://docs.python.org/reference/expressions.html

Örnek 1: 6'ya bölünürse 2 (3 kez) 6%2kalır, 0çünkü değerlendirme yapılmaz.

Örnek 2 : 7'nin 2'ye bölünmesiyle (3 kez) kalan bir 7%2süre 1olduğu için değerlendirilir 1.

Özetlemek gerekirse, bir bölünme operasyonunun kalanını ya 0da hiç kalıntı yoksa döndürür . Yani 6%26'nın kalanını 2'ye bölmek anlamına gelir.


7
Neden tüm örneklerin sağında daha büyük bir sayı var? Birisi 2'yi veren 2% 6'nın sonucunu açıklayabilir mi?
wookie

8
İlk sayı pay, ikincisi paydadır. Örnek 2'de 6'ya bölünen 0 kalan 2'dir, bu nedenle sonuç 2'dir.
David

4
Lütfen cevabınızı güncelleyin, aşağıda daha doğru cevaplar var. İçinde C / C ++ ,% Python% 'mod için' ise 'rem' içindir. örneğin - 21 % 4Python 3'tür.
azam

Lütfen nedenini açıklayabilir misiniz -11%5 = 4??
dahiya_boy

@dahiya_boy GvR'nin açıklamasını aşağıda daha az oy alan cevapma ekledim.
Paulo Scardine

143

Biraz konu dışı, %dizeyi biçimlendirme işlemlerinde %=değerleri bir dizeye koymak gibi kullanılır :

>>> x = 'abc_%(key)s_'
>>> x %= {'key':'value'}
>>> x 
'abc_value_'

Yine konu dışı, ama beni takip etmek için biraz zaman aldı biraz belgelenmiş bir özellik gibi görünüyor, ve ben bu SO sayfasının yüksek sırada olduğu Pythons modulo hesaplama ile ilgili olduğunu düşündüm.


% İçin de dize biçimlendirme başvurusu olarak kullanılan bir mantık var mı, yoksa yalnızca bu sembolün aşırı yüklenmesi bir tarih kazası mı? Bu kendi sorusu mu olmalı?
WAF

5
Belgelenmemiş mi? Ben öyle düşünmüyorum: String Formatting Operations
KurzedMetal

@KurzedMetal - %=bu sayfada görünmüyor
P. Myer Nore

@WAF %Operatör, dizenin kendisinde kullanılan yüzde belirteçlerini yansıttığı için seçildi.
MI Wright

Bunun neredeyse 3 yıl sonra olduğunu biliyorum, ama başkalarına yardımcı olabilir. İlk vurgulanan paragrafı saniye cinsinden okuyun. 5.6.2 yukarıda KurzedMetal tarafından bağlanmıştır. "X% = {}" sadece "x = x% {...}" için kısa bir formdur
Sujay Phadke

58

Gibi bir ifade x % ygeri kalanı değerlendirir x ÷ y- iyi, teknik olarak "hatırlatma" yerine "modül" dir, bu nedenle %kalan işleç olan diğer dillerle karşılaştırırsanız sonuçlar farklı olabilir . Bazı ince farklılıklar vardır (eğer pratik sonuçlarla ilgileniyorsanız "Python'un Tamsayı Bölümü Zeminleri" bölümüne de bakınız).

Öncelik işleçlerle /(bölme) ve *(çarpma) ile aynıdır .

>>> 9 / 2
4
>>> 9 % 2
1
  • 9 bölü 2 eşittir 4.
  • 4 Kez 2 8
  • 9 eksi 8 1'dir - geri kalanı.

Python gotcha : Kullandığınız Python sürümüne bağlı olarak, %(kullanımdan kaldırılmış) dize enterpolasyon operatörüdür, bu yüzden benzer bir ifadenin '12' % 2 + 3yasal olduğu otomatik tür dökümü (PHP veya JS gibi) bir dilden gelip gelmediğinize dikkat edin : in Python TypeError: not all arguments converted during string formattingmuhtemelen sizin için oldukça kafa karıştırıcı olacak.

[Python 3 için güncelleme]

Kullanıcı n00p yorumları:

9/2, pitonda 4,5'tir. Python'un size bölünmeden sonra kaç tam nesnenin kaldığını söylemesini istiyorsanız, 9/2 gibi tamsayı bölünmesi yapmanız gerekir.

Kesin olarak, tamsayı bölümü Python 2'de varsayılan olarak kullanılıyordu (unutmayın, bu cevap zaten okulda olan ve 2.x ana akım olan oğlumdan daha eski):

$ python2.7
Python 2.7.10 (default, Oct  6 2017, 22:29:07)
[GCC 4.2.1 Compatible Apple LLVM 9.0.0 (clang-900.0.31)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> 9 / 2
4
>>> 9 // 2
4
>>> 9 % 2
1

Modern Python 9 / 2sonuçlarında 4.5gerçekten:

$ python3.6
Python 3.6.1 (default, Apr 27 2017, 00:15:59)
[GCC 4.2.1 Compatible Apple LLVM 8.1.0 (clang-802.0.42)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> 9 / 2
4.5
>>> 9 // 2
4
>>> 9 % 2
1

[Güncelleme]

Kullanıcı dahiya_boy yorum oturumunda sordu:

S. Nedenini açıklayabilir misiniz -11 % 5 = 4dahiya_boy -

Bu garip, değil mi? Bunu JavaScript'te denerseniz:

> -11 % 5
-1

Bunun nedeni, JavaScript'te %"kalan" operatör iken Python'da "modül" (saat matematik) operatörü olmasıdır.

Sen alabilirsiniz GvR doğrudan açıklama :


Düzenle - dahiya_boy

Java ve iOS'ta -11 % 5 = -1ise python ve ruby'de -11 % 5 = 4.

Nedenin yarısı Paulo Scardine tarafından açıklanıyor ve açıklamanın geri kalanı burada

Java ve iOS'ta %kalan kısmı verir, yani % 11'i bölerseniz 5 verir Quotient = 2 and remainder = 1ve -11% 5 verir Quotient = -2 and remainder = -1.

Hızlı iOS'ta örnek kod.

resim açıklamasını buraya girin

Ama python hakkında konuştuğumuzda saat modülü verir. Ve aşağıdaki formülle çalışması

mod(a,n) = a - {n * Floor(a/n)}

Bu şu anlama gelir,

mod(11,5) = 11 - {5 * Floor(11/5)} => 11 - {5 * 2}

Yani, mod(11,5) = 1

Ve

mod(-11,5) = -11 - 5 * Floor(11/5) => -11 - {5 * (-3)}

Yani, mod(-11,5) = 4

Python 3.0'da örnek kod.

resim açıklamasını buraya girin


Neden Python'un Tamsayı Bölümü Zeminleri

Bugün (tekrar) Python'daki tamsayı bölümünün neden C gibi sıfıra doğru kesmek yerine sonucun tabanını döndürdüğünü açıklamam istendi.

Pozitif sayılar için sürpriz yok:

>>> 5//2
2

Ancak işlenenlerden biri negatifse, sonuç katlanır, yani sıfırdan uzağa (negatif sonsuza doğru) yuvarlanır:

>>> -5//2
-3
>>> 5//-2
-3

Bu bazı insanları rahatsız ediyor, ancak iyi bir matematiksel sebep var. Tamsayı bölme işlemi (//) ve kardeşi, modulo işlemi (%), birlikte gider ve hoş bir matematiksel ilişkiyi tatmin eder (tüm değişkenler tamsayıdır):

a/b = q with remainder r

öyle ki

b*q + r = a and 0 <= r < b

(a ve b'nin = = 0 olduğu varsayılarak).

İlişkinin negatif a (b pozitif tutmak) için uzatılmasını istiyorsanız, iki seçeneğiniz vardır: q'yu sıfıra keserseniz, r negatif olur, böylece değişmez 0 0 = abs (r) <olarak değişir, aksi takdirde q, negatif sonsuza doğru katlanabilir ve değişmez 0 0 = r <b olarak kalır. [güncelleme: bu para düzeltildi]

Matematiksel sayı teorisinde, matematikçiler her zaman ikinci seçeneği tercih ederler (bkz . Wikipedia ). Python için aynı seçimi yaptım, çünkü a işaretinin ilginç olmadığı modulo işleminin bazı ilginç uygulamaları var. POSIX zaman damgası (1970'in başlangıcından bu yana saniye) almayı ve günün saatine dönüştürmeyi düşünün. Günde 24 * 3600 = 86400 saniye olduğu için, bu hesaplama basitçe t% 86400 olur. Ancak 1970'den önce negatif sayılar kullanarak süreleri ifade edersek, "sıfıra doğru kes" kuralı anlamsız bir sonuç verirdi! Zemin kuralını kullanarak her şey yolunda gider.

Düşündüğüm diğer uygulamalar, bilgisayar grafiklerindeki piksel konumlarının hesaplanmasıdır. Eminim dahası var.

Negatif b için, bu arada, her şey ters çevrilir ve değişmez:

0 >= r > b.

Peki neden C bunu bu şekilde yapmıyor? Muhtemelen C, tasarlandığı sırada donanım bunu yapmadı. Ve donanım muhtemelen bu şekilde yapmadı çünkü en eski donanımda, negatif sayılar, ikisinin bugünlerde kullanılan tamamlayıcı gösterimi yerine (en azından tamsayılar için) "işaret + büyüklük" olarak temsil edildi. İlk bilgisayarım Kontrol Verileri anabilgisayarıydı ve tamsayılar ve şamandıralar için tamamlayıcısını kullandı. 60'lık bir model negatif sıfır demekti!

Tüm Python'un kayan nokta iskeletlerinin nereye gömüldüğünü bilen Tim Peters, bu kuralları kayan nokta modülosuna genişletme arzum hakkında bazı endişeler dile getirdi. Muhtemelen haklıdır; x çok küçük bir negatif sayı olduğunda, kesilme-negatif-sonsuzluk kuralı% x 1,0 için hassas kayıplara neden olabilir. Ama bu tamsayı modulo'unu kırmam için yeterli değil ve // ​​buna sıkıca bağlı.

PS. / Yerine // kullanıyorum, bu Python 3 sözdizimi ve ayrıca Python 2'de tamsayı bölmesini çağırdığınızı vurgulamak için izin verildi. Python 2'deki / operatörü belirsizdir, çünkü iki tamsayı işlenen için int ve float veya iki floattan farklı bir sonuç döndürür. Ama bu tamamen ayrı bir hikaye; bkz. PEP 238.

Gönderen Guido van Rossum zaman: 09:49


1
Ayrıca, help(divmod)değişmezi belgeler q, r = divmod(x y) <==> q*y + r == x.
chepner

49

Modül, bazen "saat aritmetiği" olarak tanımlanan matematiksel bir işlemdir. Sadece bir geri kalan olarak tanımlamanın yanıltıcı ve kafa karıştırıcı olduğunu görüyorum, çünkü bilgisayar biliminde bu kadar çok kullanılmasının gerçek nedenini maskeliyor. Gerçekten çevrimleri sarmak için kullanılır.

Bir saat düşünün: "Askeri" zamanda, saatlerin 0:00 - 23,59 arası bir saate baktığınızı varsayalım. Şimdi her gün gece yarısı bir şey olmasını istiyorsanız, şimdiki zaman mod 24'ün sıfır olmasını istersiniz:

eğer (saat% 24 == 0):

Tarihin tüm saatlerini 24 saat boyunca tekrar eden bir dairenin etrafına sararak düşünebilirsiniz ve günün mevcut saati sonsuz sayıda sayı 24'tür. döngülerle başa çıkmak ve bilgisayar biliminde çok önemlidir. Dizinin etrafına sarmak için de kullanılır, dizinin sonuna ulaştıktan sonra dizini sonuna kadar geri sarmak için modülü kullanır.


1
Python'da şu şekilde uygulanmaktadır:a % b = a - b * floor(a/b)
Aiman ​​Al-Eryani


7

Çoğu dilde modül için% kullanılır . Python bir istisna değildir.


11
Görebildiğim kadarıyla, Python, modül için% kullanması nedeniyle olağandışı; Fortran, C / C ++ ve Java, kalanları ifade etmek için% kullanır. (Bkz. Stackoverflow.com/questions/13683563/… , farklar negatif ve kesirli değerlerin işlenme biçimindedir.) Ayırım yapan diller (örn. Ada, Haskell ve Şema) "rem" ve "mod" sözcüklerini kullanır (veya "geri kalan" ve "modulo") yerine%.
Jim Pivarski

5
Güncelleme: Bu büyük modulo / kalan operasyonlar tablosunu en.wikipedia.org/wiki/Modulo_operation diliyle buldum . Python alışılmadık ancak benzersiz değil (örneğin, TCL ve Lua Python'un sözleşmesini paylaşıyor.)
Jim Pivarski


4

x % ybölmede kalan hesaplar xbölünmesiyle yburada bölüm bir tamsayıdır . Kalanın işareti var y.


Python 3'te hesaplama elde edilir 6.75; Bunun nedeni, /Python 2'de (varsayılan olarak) tamsayı bölümü değil, gerçek bir bölünme yapılmasıdır. Python 2'de 1 / 4sonuç aşağı yuvarlandığı için 0 verir.

Tamsayı bölümü, Python 3'te //operatörle de yapılabilir , böylece 7'yi elde etmek için şunları yapabilirsiniz:

3 + 2 + 1 - 5 + 4 % 2 - 1 // 4 + 6

Ayrıca, sadece çizgi ekleyerek Python 2'de Python stil bölümünü alabilirsiniz.

from __future__ import division

her kaynak dosyadaki ilk kaynak kodu satırı olarak.


8
Unutmayın çocuklar #yorumlar içindir ve //bir operatör.
Mike Causer

3

Modül operatörü, genellikle tamsayılarda kalan bölümler için kullanılır, ancak Python'da kayan nokta sayıları için kullanılabilir.

http://docs.python.org/reference/expressions.html

% (Modulo) operatörü, ilk argümanın ikinciye bölünmesinden kalanını verir. Sayısal bağımsız değişkenler önce ortak bir türe dönüştürülür. Sıfır sağ argümanı ZeroDivisionError istisnasını yükseltir. Değişkenler kayan nokta sayıları olabilir, örn.,% 3.14 0.7, 0.34'e eşittir (3.14, 4 * 0.7 + 0.34'e eşit olduğundan.) Modulo operatörü her zaman ikinci işleneni (veya sıfır) ile aynı işarete sahip bir sonuç verir; sonucun mutlak değeri, ikinci işlenenin mutlak değerinden kesinlikle daha küçüktür [2].


3

Bu bir modulo işlemi değil, eski moda C tarzı dize biçimlendirme operatörü olması dışında bir modulo işlemi . Ayrıntılar için buraya bakın. Bunların çoğunu mevcut kodda göreceksiniz.


3

Ayrıca, yararlı bir yerleşik işlev vardır divmod:

divmod (a, b)

İki (karmaşık olmayan) sayıyı bağımsız değişken olarak alın ve uzun bölümü kullanırken bölümlerinden ve kalanlarından oluşan bir çift sayı döndürün.


2

Farkında olmak

(3 +2 + 1 - 5) + (4 % 2) - (1/4) + 6

köşeli parantezlerde bile Python 3.4'te hesaplanırsa 7 yerine 6,75 olur.


Ve '/' operatörü de anlaşılması kolay değil (python2.7): deneyin ...

- 1/4

1 - 1/4

Bu biraz konu dışı, ancak yukarıdaki ifadeyi değerlendirirken dikkate alınmalıdır :)


2
Bu nasıl 7 olurdu? Basitleştirir (1)+(0)-(0.25)+(6).
J.Steve

1

% Çevrimiçi kullanımı için özel kullanım durumlarını kolayca bulmak benim için zordu, örneğin neden kesirli modül bölümü veya negatif modül bölümü yapmak cevabını veriyor. Umarım bu gibi soruların netleştirilmesine yardımcı olur:

Modül Bölümü Genel Olarak:

Modül bölme, matematiksel bölme işleminin geri kalanını döndürür. Aşağıdaki gibi yapar:

Diyelim ki 5 temettü ve 2 bölen var, aşağıdaki bölme işlemi (x'e eşittir) olurdu:

dividend = 5
divisor = 2

x = 5/2 
  1. Modül hesaplamasındaki ilk adım tamsayı bölme yapmaktır:

    x_int = 5 // 2 (python'da tamsayı bölme çift eğik çizgi kullanır)

    x_int = 2

  2. Daha sonra, x_int çıktısı bölen ile çarpılır:

    x_mult = x_int * bölen x_mult = 4

  3. Son olarak, temettü x_mult'tan çıkarılır

    temettü - x_mult = 1

  4. Bu nedenle modül işlemi 1 döndürür:

    % 5 2 = 1

Modülü bir kesriye uygulama

Example: 2 % 5 

Bir fraksiyona uygulandığında modülün hesaplanması yukarıdaki ile aynıdır; ancak, bölen temettüden daha büyük olduğunda, tamsayı bölümünün sıfır değerine neden olacağını belirtmek önemlidir:

dividend = 2 
divisor = 5

Tamsayı bölümü 0 ile sonuçlanırken; bu nedenle, yukarıdaki 3. adım gerçekleştirildiğinde, temettünün değeri (sıfırdan çıkarılır) üzerinden taşınır:

dividend - 0 = 2  —> 2 % 5 = 2 

Modülü bir eksiğe uygulama

Kat bölümü, tamsayı bölümünün değerinin en düşük tamsayı değerine yuvarlandığı oluşur:

import math 

x = -1.1
math.floor(-1.1) = -2 

y = 1.1
math.floor = 1

Bu nedenle, tamsayı bölme yaptığınızda beklediğinizden farklı bir sonuç elde edebilirsiniz!

Yukarıdaki adımları aşağıdaki temettü ve bölen üzerine uygulamak, modül kavramını göstermektedir:

dividend: -5 
divisor: 2 

1. Adım: Tamsayı bölümünü uygulayın

x_int = -5 // 2  = -3

Adım 2: Tamsayı bölümünün sonucunu bölen ile çarpın

x_mult = x_int * 2 = -6

Adım 3: Temettüyü çarpılan değişkenten çıkarın, çift negatife dikkat edin.

dividend - x_mult = -5 -(-6) = 1

Bu nedenle:

-5 % 2 = 1

0

% (Modulo) operatörü, ilk argümanın ikinciye bölünmesinden kalanını verir. Sayısal bağımsız değişkenler önce ortak bir türe dönüştürülür.

3 + 2 + 1-5 + 4% 2-1 / 4 + 6 = 7

Bu, operatör önceliğine dayanır.


0

%olduğu modülo . 3 % 2 = 1,4 % 2 = 0

/ (bu örnekte bir tam sayı) bölümüdür, yani:

3 + 2 + 1 - 5 + 4 % 2 - 1 / 4 + 6
1 + 4%2 - 1/4 + 6
1 + 0 - 0 + 6
7



0

Modulus - Sol el işlenenini sağ el işlenenine böler ve geri kalanını döndürür.

Eğer yardımcı olursa:

1:0> 2%6
=> 2
2:0> 8%6
=> 2
3:0> 2%6 == 8%6
=> true

... ve bunun gibi.


0

Modül operatörünü (%) kavramanın en kolay yolunun uzun bölünme yoluyla olduğunu gördüm. Geri kalan kısımdır ve bir sayının çift veya tek olması için faydalı olabilir:

4%2 = 0

  2
2|4
 -4
  0


11%3 = 2

  3
3|11
 -9
  2

bölümün geri kalanını almak için fazla bir şey
vermez
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.