Apa hasil dari% dalam Python?


241

Apa %perhitungannya? Sepertinya saya tidak tahu apa fungsinya.

Apakah itu berhasil persen perhitungan misalnya: 4 % 2ternyata sama dengan 0. Bagaimana?

Jawaban:


304

Operator% (modulo) menghasilkan sisanya dari pembagian argumen pertama oleh yang kedua. Argumen numerik pertama kali dikonversi ke tipe umum. Argumen nol kanan memunculkan pengecualian ZeroDivisionError. Argumen mungkin angka floating point, misalnya, 3,14% 0,7 sama dengan 0,34 (karena 3,14 sama dengan 4 * 0,7 + 0,34.) Operator modulo selalu menghasilkan hasil dengan tanda yang sama dengan operan kedua (atau nol); nilai absolut dari hasil ini benar-benar lebih kecil dari nilai absolut dari operan kedua [2].

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

Contoh 1: 6%2 dievaluasi 0karena tidak ada sisa jika 6 dibagi 2 (3 kali).

Contoh 2 : 7%2dievaluasi 1karena ada sisa 1kapan 7 dibagi 2 (3 kali).

Jadi untuk meringkas itu, ia mengembalikan sisa operasi divisi, atau 0jika tidak ada sisanya. Jadi 6%2berarti menemukan sisa 6 dibagi 2.


7
Mengapa semua contoh memiliki angka lebih besar di sebelah kanan? Adakah yang bisa menjelaskan hasil 2% 6 yang menghasilkan 2?
wookie

8
Angka pertama adalah pembilang dan yang kedua adalah penyebut. Dalam contoh Anda 2 dibagi dengan 6 adalah 0 sisa 2, oleh karena itu hasilnya adalah 2.
David

4
Harap perbarui jawaban Anda, ada jawaban yang lebih akurat di bawah ini. Dalam C / C ++ % adalah untuk 'rem' sedangkan dalam Python% adalah untuk 'mod'. misal - 21 % 43 dalam Python.
azam

Bisakah Anda jelaskan mengapa -11%5 = 4??
dahiya_boy

@dahiya_boy Saya telah menambahkan penjelasan GvR ke jawaban saya yang kurang terunggul di bawah ini.
Paulo Scardine

143

Agak di luar topik, %ini juga digunakan dalam operasi pemformatan string seperti %=untuk mengganti nilai menjadi string:

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

Sekali lagi, di luar topik, tetapi tampaknya ini adalah fitur yang sedikit terdokumentasi yang membuat saya perlu waktu untuk melacak, dan saya pikir itu terkait dengan perhitungan modulo Python yang peringkat halaman SO ini sangat tinggi.


Apakah ada logika untuk% juga digunakan sebagai referensi pemformatan string atau hanya kebetulan sejarah bahwa simbol itu kelebihan beban? Haruskah ini menjadi pertanyaannya sendiri?
WAF

5
Dokumentasi yang buruk? Saya tidak berpikir begitu: Operasi Pemformatan Tali
KurzedMetal

@KurzedMetal - %=tidak muncul di halaman itu
P. Myer Nore

@ WAF %Operator dipilih karena mencerminkan persen- penentu yang digunakan dalam string itu sendiri.
MI Wright

@ P.MyerNore Saya tahu ini hampir 3 tahun kemudian, tetapi dapat membantu orang lain. Baca para yang disorot pertama dalam dtk. 5.6.2 ditautkan di atas oleh KurzedMetal. "X% = {}" hanyalah bentuk pendek untuk "x = x% {...}"
Sujay Phadke

58

Ekspresi seperti x % ymengevaluasi hingga sisa x ÷ y- well, secara teknis itu adalah "modulus" dan bukan "pengingat" sehingga hasilnya mungkin berbeda jika Anda membandingkan dengan bahasa lain di mana %operator sisanya. Ada beberapa perbedaan halus (jika Anda tertarik pada konsekuensi praktis lihat juga "Mengapa Lantai Divisi Integer Python" di bawah).

Presedensi sama dengan operator /(divisi) dan *(perkalian).

>>> 9 / 2
4
>>> 9 % 2
1
  • 9 dibagi 2 sama dengan 4.
  • 4 kali 2 adalah 8
  • 9 minus 8 adalah 1 - sisanya.

Python gotcha : tergantung pada versi Python yang Anda gunakan, %juga operator interpolasi string (tidak digunakan), jadi waspadalah jika Anda berasal dari bahasa dengan casting tipe otomatis (seperti PHP atau JS) di mana ekspresi seperti '12' % 2 + 3legal: di Python itu akan menghasilkan TypeError: not all arguments converted during string formattingyang mungkin akan cukup membingungkan untuk Anda.

[perbarui untuk Python 3]

Komentar pengguna n00p:

9/2 adalah 4,5 dalam python. Anda harus melakukan pembagian integer seperti ini: 9 // 2 jika Anda ingin python memberi tahu Anda berapa banyak objek yang tersisa setelah pembagian (4).

Lebih tepatnya, pembagian integer dulunya adalah default di Python 2 (ingatlah, jawaban ini lebih tua dari anak saya yang sudah sekolah dan pada saat itu 2.x adalah arus utama):

$ 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

Dalam 9 / 2hasil Python modern 4.5memang:

$ 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

[memperbarui]

Pengguna dahiya_boy bertanya dalam sesi komentar:

P. Bisakah Anda jelaskan alasannya -11 % 5 = 4- dahiya_boy

Ini aneh, bukan? Jika Anda mencoba ini dalam JavaScript:

> -11 % 5
-1

Ini karena dalam JavaScript %adalah operator "sisanya" sedangkan di Python adalah operator "modulus" (jam matematika).

Anda bisa mendapatkan penjelasan langsung dari GvR :


Edit - dahiya_boy

Di Jawa dan iOS -11 % 5 = -1sedangkan di python dan ruby -11 % 5 = 4.

Separuh dari alasannya dijelaskan oleh Paulo Scardine , dan sisa penjelasannya ada di bawah sini

Di Java dan iOS, %beri sisanya yang berarti jika Anda membagi 11% 5 memberi Quotient = 2 and remainder = 1dan -11% 5 memberi Quotient = -2 and remainder = -1.

Kode contoh di iOS cepat.

masukkan deskripsi gambar di sini

Tetapi ketika kita berbicara tentang python memberikan modulus jam. Dan kerjanya dengan formula di bawah ini

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

Itu berarti,

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

Begitu, mod(11,5) = 1

Dan

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

Begitu, mod(-11,5) = 4

Kode contoh dalam python 3.0.

masukkan deskripsi gambar di sini


Mengapa Lantai Divisi Integer Python

Saya diminta (lagi) hari ini untuk menjelaskan mengapa pembagian integer di Python mengembalikan lantai hasil alih-alih memotong ke nol seperti C.

Untuk angka positif, tidak ada kejutan:

>>> 5//2
2

Tetapi jika salah satu operan negatif, hasilnya adalah lantai, yaitu dibulatkan dari nol (menuju infinity negatif):

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

Ini mengganggu sebagian orang, tetapi ada alasan matematika yang bagus. Operasi pembagian integer (//) dan saudara kandungnya, operasi modulo (%), berjalan bersama dan memuaskan hubungan matematika yang bagus (semua variabel adalah integer):

a/b = q with remainder r

seperti yang

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

(dengan asumsi a dan b adalah> = 0).

Jika Anda ingin hubungan diperluas menjadi negatif (menjaga b positif), Anda memiliki dua pilihan: jika Anda memotong q menuju nol, r akan menjadi negatif, sehingga invarian berubah menjadi 0 <= abs (r) <jika tidak, Anda can lantai q menuju infinity negatif, dan invarian tetap 0 <= r <b. [perbarui: perbaiki para ini]

Dalam teori bilangan matematika, ahli matematika selalu lebih suka pilihan terakhir (lihat misalnya Wikipedia ). Untuk Python, saya membuat pilihan yang sama karena ada beberapa aplikasi menarik dari operasi modulo di mana tanda a tidak menarik. Pertimbangkan untuk mengambil stempel waktu POSIX (detik sejak awal 1970) dan mengubahnya menjadi waktu sehari. Karena ada 24 * 3600 = 86400 detik dalam sehari, perhitungan ini hanya t% 86400. Tetapi jika kita menyatakan waktu sebelum 1970 menggunakan angka negatif, aturan "truncate towards zero" akan memberikan hasil yang tidak berarti! Menggunakan aturan lantai semuanya bekerja dengan baik.

Aplikasi lain yang saya pikirkan adalah perhitungan posisi piksel dalam grafik komputer. Saya yakin masih ada lagi.

Untuk b negatif, omong-omong, semuanya hanya membalik, dan invarian menjadi:

0 >= r > b.

Jadi mengapa C tidak melakukannya dengan cara ini? Mungkin perangkat keras tidak melakukan ini pada saat C dirancang. Dan perangkat keras mungkin tidak melakukannya dengan cara ini karena dalam perangkat keras tertua, angka negatif direpresentasikan sebagai "tanda + besarnya" daripada representasi komplemen dua yang digunakan hari ini (setidaknya untuk bilangan bulat). Komputer pertama saya adalah mainframe Data Kontrol dan menggunakan komplemen seseorang untuk integer dan juga float. Pola 60 yang berarti nol negatif!

Tim Peters, yang tahu di mana semua kerangka titik apung Python dimakamkan, telah menyatakan kekhawatiran tentang keinginan saya untuk memperluas aturan ini ke modulo titik apung. Dia mungkin benar; aturan truncate-towards-negative-infinity dapat menyebabkan hilangnya presisi untuk x% 1.0 ketika x adalah angka negatif yang sangat kecil. Tapi itu tidak cukup bagi saya untuk mematahkan bilangan bulat modulo, dan / / ditambah dengan itu.

PS. Perhatikan bahwa saya menggunakan // bukannya / - ini adalah sintaks Python 3, dan juga diizinkan dalam Python 2 untuk menekankan bahwa Anda tahu Anda sedang memanggil divisi integer. / Operator di Python 2 adalah ambigu, karena mengembalikan hasil yang berbeda untuk dua operan bilangan bulat daripada untuk int dan float atau dua float. Tapi itu cerita yang sama sekali terpisah; lihat PEP 238.

Diposting oleh Guido van Rossum pada jam 9:49


1
Juga, help(divmod)dokumentasikan invarian q, r = divmod(x y) <==> q*y + r == x.
chepner

49

Modulus adalah operasi matematika, kadang-kadang digambarkan sebagai "aritmatika jam." Saya menemukan bahwa menggambarkannya hanya sebagai sisa adalah menyesatkan dan membingungkan karena menutupi alasan sebenarnya itu digunakan begitu banyak dalam ilmu komputer. Ini benar-benar digunakan untuk membungkus siklus.

Pikirkan jam: Misalkan Anda melihat jam di waktu "militer", di mana rentang waktu berlangsung dari 0:00 - 23,59. Sekarang jika Anda menginginkan sesuatu terjadi setiap hari pada tengah malam, Anda ingin waktu saat ini mod 24 menjadi nol:

jika (jam% 24 == 0):

Anda dapat memikirkan semua jam dalam sejarah yang melingkari lingkaran 24 jam berulang-ulang dan jam saat ini adalah angka yang sangat panjang mod 24. Ini adalah konsep yang jauh lebih mendalam dari sekadar sisa, itu adalah cara matematika untuk berurusan dengan siklus dan sangat penting dalam ilmu komputer. Ini juga digunakan untuk membungkus array, memungkinkan Anda untuk meningkatkan indeks dan menggunakan modulus untuk membungkus kembali ke awal setelah Anda mencapai akhir array.


1
Ini adalah bagaimana ini diimplementasikan dalam Python:a % b = a - b * floor(a/b)
Aiman ​​Al-Eryani


7

Dalam sebagian besar bahasa% digunakan untuk modulus . Python tidak terkecuali.


11
Sejauh yang saya bisa lihat, Python tidak biasa karena menggunakan% untuk modulus; Fortran, C / C ++, dan Java menggunakan% artinya sisanya. (Lihat stackoverflow.com/questions/13683563/… , perbedaannya terletak pada bagaimana nilai-nilai negatif dan fraksional ditangani.) Bahasa-bahasa yang membuat perbedaan (misalnya Ada, Haskell, dan Skema) menggunakan kata-kata "rem" dan "mod" (atau "sisa" dan "modulo") daripada%.
Jim Pivarski

5
Pembaruan: Saya menemukan tabel besar operasi modulo / sisanya berdasarkan bahasa en.wikipedia.org/wiki/Modulo_operation . Python tidak biasa tetapi tidak unik (misalnya, TCL dan Lua berbagi konvensi Python.)
Jim Pivarski

5

% Operator Modulo juga dapat digunakan untuk mencetak string (Sama seperti dalam C) sebagaimana didefinisikan di Google https://developers.google.com/edu/python/strings .

      # % operator
  text = "%d little pigs come out or I'll %s and %s and %s" % (3, 'huff', 'puff', 'blow down')

Ini tampaknya menggigit topik tetapi pasti akan membantu seseorang.


4

x % ymenghitung sisa divisi xdibagi dengan di ymana hasil bagi adalah bilangan bulat . Sisanya memiliki tanda y.


Pada Python 3 perhitungan menghasilkan 6.75; ini karena /melakukan pembagian yang benar, bukan pembagian bilangan bulat seperti (secara default) pada Python 2. Pada Python 2 1 / 4memberikan 0, karena hasilnya dibulatkan ke bawah.

Divisi integer dapat dilakukan pada Python 3 juga, dengan //operator, sehingga untuk mendapatkan 7 sebagai hasilnya, Anda dapat menjalankan:

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

Juga, Anda bisa mendapatkan pembagian gaya Python di Python 2, hanya dengan menambahkan baris

from __future__ import division

sebagai baris kode sumber pertama di setiap file sumber.


8
Ingat anak #- anak adalah untuk komentar dan //operator.
Mike Causer

3

Modulus operator, digunakan untuk pembagian sisa pada bilangan bulat, biasanya, tetapi dalam Python dapat digunakan untuk angka floating point.

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

Operator% (modulo) menghasilkan sisanya dari pembagian argumen pertama oleh yang kedua. Argumen numerik pertama kali dikonversi ke tipe umum. Argumen nol kanan memunculkan pengecualian ZeroDivisionError. Argumen mungkin angka floating point, misalnya, 3,14% 0,7 sama dengan 0,34 (karena 3,14 sama dengan 4 * 0,7 + 0,34.) Operator modulo selalu menghasilkan hasil dengan tanda yang sama dengan operan kedua (atau nol); nilai absolut dari hasil ini benar-benar lebih kecil dari nilai absolut dari operan kedua [2].


3

Ini adalah operasi modulo, kecuali ketika itu adalah operator pemformatan string gaya-C kuno, bukan operasi modulo . Lihat di sini untuk detailnya. Anda akan melihat banyak dari ini dalam kode yang ada.


3

Selain itu, ada fungsi bawaan yang berguna yang disebut divmod:

divmod (a, b)

Ambil dua angka (bukan kompleks) sebagai argumen dan kembalikan sepasang angka yang terdiri dari hasil bagi dan sisanya ketika menggunakan pembagian panjang.


2

Sadarilah itu

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

bahkan dengan tanda kurung menghasilkan 6,75 bukannya 7 jika dihitung dengan Python 3.4.


Dan operator '/' juga tidak mudah dimengerti (python2.7): coba ...

- 1/4

1 - 1/4

Ini agak di luar topik di sini, tetapi harus dipertimbangkan ketika mengevaluasi ungkapan di atas :)


2
Bagaimana ini akan menjadi 7? Menyederhanakan (1)+(0)-(0.25)+(6).
J.Steve

1

Sulit bagi saya untuk dengan mudah menemukan kasus penggunaan khusus untuk penggunaan% online, misalnya mengapa melakukan pembagian modulus fraksional atau pembagian modulus negatif menghasilkan jawaban yang benar. Semoga ini bisa membantu mengklarifikasi pertanyaan seperti ini:

Divisi Modulus Secara Umum:

Divisi modulus mengembalikan sisa operasi divisi matematika. Apakah itu sebagai berikut:

Katakanlah kita memiliki dividen 5 dan pembagi 2, operasi divisi berikut akan (disamakan dengan x):

dividend = 5
divisor = 2

x = 5/2 
  1. Langkah pertama dalam perhitungan modulus adalah melakukan pembagian integer:

    x_int = 5 // 2 (pembagian integer dalam python menggunakan double slash)

    x_int = 2

  2. Selanjutnya, output x_int dikalikan dengan pembagi:

    x_mult = x_int * pembagi x_mult = 4

  3. Terakhir, dividen dikurangi dari x_mult

    dividend - x_mult = 1

  4. Operasi modulus, oleh karena itu, mengembalikan 1:

    5% 2 = 1

Aplikasi untuk menerapkan modulus ke sebagian kecil

Example: 2 % 5 

Perhitungan modulus ketika diterapkan pada fraksi sama dengan di atas; Namun, penting untuk dicatat bahwa divisi integer akan menghasilkan nilai nol ketika pembagi lebih besar dari dividen:

dividend = 2 
divisor = 5

Divisi integer menghasilkan 0 sedangkan; oleh karena itu, ketika langkah 3 di atas dilakukan, nilai dividen dijalankan (dikurangi dari nol):

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

Aplikasi untuk menerapkan modulus ke negatif

Pembagian lantai terjadi di mana nilai divisi integer dibulatkan ke nilai integer terendah:

import math 

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

y = 1.1
math.floor = 1

Karena itu, ketika Anda melakukan pembagian integer Anda mungkin mendapatkan hasil yang berbeda dari yang Anda harapkan!

Menerapkan langkah-langkah di atas pada dividen dan pembagi berikut menggambarkan konsep modulus:

dividend: -5 
divisor: 2 

Langkah 1: Terapkan pembagian integer

x_int = -5 // 2  = -3

Langkah 2: Gandakan hasil pembagian integer dengan pembagi

x_mult = x_int * 2 = -6

Langkah 3: Kurangi dividen dari variabel yang dikalikan, perhatikan negatif ganda.

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

Karena itu:

-5 % 2 = 1

0

Operator% (modulo) menghasilkan sisanya dari pembagian argumen pertama oleh yang kedua. Argumen numerik pertama kali dikonversi ke tipe umum.

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

Ini didasarkan pada prioritas operator.


0

%adalah modulo . 3 % 2 = 1,4 % 2 = 0

/ adalah (bilangan bulat dalam hal ini) divisi, jadi:

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



0

Modulus - Membagi operan tangan kiri dengan operan tangan kanan dan mengembalikan sisanya.

Jika itu membantu:

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

... dan seterusnya.


0

Saya telah menemukan bahwa cara termudah untuk memahami operator modulus (%) adalah melalui divisi panjang. Ini adalah sisanya dan dapat berguna dalam menentukan angka menjadi genap atau ganjil:

4%2 = 0

  2
2|4
 -4
  0


11%3 = 2

  3
3|11
 -9
  2

memberikan sisa dari sebuah divisi tidak banyak untuk mengambil
DeafaltCoder
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.