wake-up-neo.com

Was bedeutet das Prozentzeichen in Python?

Im Tutorial gibt es ein Beispiel für das Finden von Primzahlen:

>>> for n in range(2, 10):
...     for x in range(2, n):
...         if n % x == 0:
...             print(n, 'equals', x, '*', n//x)
...             break
...     else:
...         # loop fell through without finding a factor
...         print(n, 'is a prime number')
...

Ich verstehe, dass der doppelte == ein Test auf Gleichheit ist, aber ich verstehe den if n % x-Teil nicht. Als könnte ich jeden Teil verbal durchgehen und sagen, was die Aussage für das Beispiel macht. Aber ich verstehe nicht, wie das Prozentzeichen fällt. 

Was sagt if n % x eigentlich?

42
Lonnie Price

Modul-Operator; gibt den Rest des linken Werts geteilt durch den rechten Wert an. Mögen:

3 % 1 wäre gleich Null (da sich 3 gleichmäßig durch 1 teilt)

3 % 2 würde 1 sein (da 3 durch 2 dividiert, ergibt sich ein Rest von 1).

50
inkedmn

% Macht zwei Dinge, abhängig von seinen Argumenten. In diesem Fall fungiert es als Modulo-Operator, dh wenn es sich bei den Argumenten um Zahlen handelt, wird das erste durch das zweite geteilt und das rest zurückgegeben. 34 % 10 == 4, da 34 durch 10 geteilt wird, drei, mit einem Rest von vier. 

Wenn das erste Argument eine Zeichenfolge ist, wird es mit dem zweiten Argument formatiert. Dies ist ein bisschen involviert, daher werde ich auf die Dokumentation verweisen, aber nur als Beispiel: 

>>> "foo %d bar" % 5
'foo 5 bar'

Das String-Formatierungsverhalten wird jedoch ab Python 3.1 zugunsten des string.format()-Mechanismus ergänzt:

Die hier beschriebenen Formatierungsvorgänge weisen eine Vielzahl von Macken auf, die zu einer Reihe von häufigen Fehlern führen (z. B., dass Tupel und Wörterbücher nicht korrekt angezeigt werden). Die Verwendung der neueren str.format() - Schnittstelle hilft, diese Fehler zu vermeiden, und bietet im Allgemeinen eine leistungsfähigere, flexiblere und erweiterbarere Methode zum Formatieren von Text.

Und zum Glück sind fast alle neuen Funktionen auch ab Python 2.6 verfügbar.

Dies ist zwar etwas außerhalb des Themas, da die Leute dies finden werden, wenn sie nach "Prozentzeichen in Python" suchen (wie ich), ich wollte jedoch beachten, dass das% -Zeichen auch dazu benutzt wird, um eine "magische" Funktion in iPython voranzustellen: https://ipython.org/ipython-doc/3/interactive/tutorial.html#magic-functions

9
Stephen

Was bedeutet das Prozentzeichen?

Es ist ein Operator in Python, der je nach Kontext mehrere Dinge bedeuten kann. In den anderen Antworten wurde bereits viel erwähnt (oder angedeutet), aber ich dachte, es könnte hilfreich sein, eine umfassendere Zusammenfassung bereitzustellen.

% für Zahlen: Modulo-Betrieb/Rest/Rest

Das Prozentzeichen ist ein -Operator in Python . Es wird beschrieben als:

x % y       remainder of x / y

So erhalten Sie den Rest/Rest, den _ ​​bleibt, wenn Sie "x" durch y "y" teilen. Im Allgemeinen (zumindest in Python) eine Zahl x und einen Divisor y gegeben:

x == y * (x // y) + (x % y)

Zum Beispiel, wenn Sie 5 durch 2 teilen:

>>> 5 // 2
2
>>> 5 % 2
1

>>> 2 * (5 // 2) + (5 % 2)
5

Im Allgemeinen verwenden Sie die modulo-Operation, um zu testen, ob eine Zahl gleichmäßig durch eine andere Zahl geteilt wird. Dies liegt daran, dass ein Vielfaches einer Zahl modulo mit dieser Zahl 0 zurückgibt:

>>> 15 % 5  # 15 is 3 * 5
0

>>> 81 % 9  # 81 is 9 * 9
0

So wird es in Ihrem Beispiel verwendet. Es kann keine Primzahl sein, wenn es sich um ein Vielfaches einer anderen Zahl handelt (außer sich selbst und einer).

if n % x == 0:
    break

Wenn Sie der Meinung sind, dass n % x == 0 nicht sehr beschreibend ist, könnten Sie ihn in eine andere Funktion mit einem aussagekräftigeren Namen einfügen:

def is_multiple(number, divisor):
    return number % divisor == 0

...

if is_multiple(n, x):
    break

Anstelle von is_multiple könnte es auch evenly_divides oder etwas Ähnliches heißen. Das wird hier getestet.

Ähnlich wie häufig wird festgestellt, ob eine Zahl "ungerade" oder "gerade" ist:

def is_odd(number):
    return number % 2 == 1

def is_even(number):
    return number % 2 == 0

In einigen Fällen wird es auch für die Indexierung von Arrays/Listen verwendet, wenn ein Wrap-around (Radfahren) -Verhalten gewünscht wird. Dann modulo Sie einfach den "Index" um die "Länge des Arrays", um dies zu erreichen:

>>> l = [0, 1, 2]
>>> length = len(l)
>>> for index in range(10):
...     print(l[index % length])
0
1
2
0
1
2
0
1
2
0

Beachten Sie, dass es für diesen Operator auch eine Funktion in der Standardbibliothek operator.mod (und den Alias ​​ operator.__mod__ ) gibt:

>>> import operator
>>> operator.mod(5, 2)  # equivalent to 5 % 2
1

Es gibt aber auch die erweiterte Zuordnung %=, die das Ergebnis der Variablen zurückgibt:

>>> a = 5
>>> a %= 2  # identical to: a = a % 2
>>> a
1

% für Zeichenfolgen: printf-style Zeichenfolgenformatierung

Für Strings ist die Bedeutung völlig anders, da es einseitig (meiner Meinung nach die begrenzteste und hässlichste) für die String-Formatierung ist:

>>> "%s is %s." % ("this", "good") 
'this is good'

Hier steht % in der Zeichenfolge für einen Platzhalter gefolgt von einer Formatierungsspezifikation. In diesem Fall habe ich %s verwendet, was bedeutet, dass eine Zeichenfolge erwartet wird. Dann folgt auf die Zeichenfolge ein %, der angibt, dass die Zeichenfolge auf der linken Seite von der rechten Seite formatiert wird. In diesem Fall wird der erste %s durch das erste Argument this und der zweite %s durch das zweite Argument (good) ersetzt.

Beachten Sie, dass es viel bessere (wahrscheinlich meinungsbasierte) Möglichkeiten gibt, Strings zu formatieren:

>>> "{} is {}.".format("this", "good")
'this is good.'

% in Jupyter/IPython: magische Befehle

So zitieren Sie die docs :

An Jupyter-Benutzer: Magics sind spezifisch für den IPython-Kernel und werden von diesem bereitgestellt. Ob Magics auf einem Kernel verfügbar sind, entscheidet der Kernel-Entwickler pro Kernel. Um ordnungsgemäß zu funktionieren, muss Magics ein Syntaxelement verwenden, das in der zugrunde liegenden Sprache nicht gültig ist. Der IPython-Kernel verwendet beispielsweise das Syntaxelement % für Magics, da % kein gültiger unärer Operator in Python ist. Das Syntaxelement hat zwar Bedeutung in anderen Sprachen.

Dies wird regelmäßig in Jupyter-Notebooks und ähnlichem verwendet:

In [1]:  a = 10
         b = 20
         %timeit a + b   # one % -> line-magic

54.6 ns ± 2.7 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)

In [2]:  %%timeit  # two %% -> cell magic 
         a ** b

362 ns ± 8.4 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)

Der %-Operator für Arrays (im NumPy/Pandas-Ökosystem)

Der %-Operator ist immer noch der Modulo-Operator, wenn er auf diese Arrays angewendet wird. Er gibt jedoch ein Array zurück, das den Rest jedes Elements im Array enthält:

>>> import numpy as np
>>> a = np.arange(10)
>>> a
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])

>>> a % 2
array([0, 1, 0, 1, 0, 1, 0, 1, 0, 1])

Anpassen des %-Operators für Ihre eigenen Klassen

Natürlich können Sie die Funktionsweise Ihrer eigenen Klassen anpassen, wenn der %-Operator auf sie angewendet wird. Im Allgemeinen verwenden Sie sollten nur zur Implementierung von Modulo-Operationen! Aber das ist eine Richtlinie, keine harte Regel.

Ein einfaches Beispiel, das zeigt, wie es funktioniert:

class MyNumber(object):
    def __init__(self, value):
        self.value = value

    def __mod__(self, other):
        print("__mod__ called on '{!r}'".format(self))
        return self.value % other

    def __repr__(self):
        return "{self.__class__.__name__}({self.value!r})".format(self=self)

Dieses Beispiel ist nicht wirklich nützlich. Es wird nur gedruckt und der Operator an den gespeicherten Wert delegiert. Es zeigt jedoch an, dass __mod__ aufgerufen wird, wenn % auf eine Instanz angewendet wird:

>>> a = MyNumber(10)
>>> a % 2
__mod__ called on 'MyNumber(10)'
0

Beachten Sie, dass es auch für %= funktioniert, ohne dass __imod__ explizit implementiert werden muss:

>>> a = MyNumber(10)
>>> a %= 2
__mod__ called on 'MyNumber(10)'

>>> a
0

Sie können jedoch auch __imod__ explizit implementieren, um die erweiterte Zuordnung zu überschreiben:

class MyNumber(object):
    def __init__(self, value):
        self.value = value

    def __mod__(self, other):
        print("__mod__ called on '{!r}'".format(self))
        return self.value % other

    def __imod__(self, other):
        print("__imod__ called on '{!r}'".format(self))
        self.value %= other
        return self

    def __repr__(self):
        return "{self.__class__.__name__}({self.value!r})".format(self=self)

Jetzt wird %= explizit überschrieben, um direkt zu arbeiten:

>>> a = MyNumber(10)
>>> a %= 2
__imod__ called on 'MyNumber(10)'

>>> a
MyNumber(0)
5
MSeifert

Der Modul-Operator. Der Rest, wenn Sie zwei Zahlen teilen.

Zum Beispiel:

>>> 5 % 2 = 1 # remainder of 5 divided by 2 is 1
>>> 7 % 3 = 1 # remainer of 7 divided by 3 is 1
>>> 3 % 1 = 0 # because 1 divides evenly into 3
1
user1031446

In Python 2.6 führte der '%'-Operator einen Modul aus. Ich glaube nicht, dass sie es in 3.0.1 geändert haben

Der Modulo-Operator teilt Ihnen den Rest einer Division aus zwei Zahlen mit. 

1
Jon W

Es prüft, ob das Modulo der Division liegt. Wenn Sie zum Beispiel alle Zahlen von 2 bis n durchlaufen und prüfen, ob n durch eine der Zahlen dazwischen teilbar ist Einfach ausgedrückt: Sie prüfen, ob eine bestimmte Zahl n eine Primzahl ist. (Hinweis: Sie können bis zu n/2 prüfen).

1
laginimaineb

Blockquote x% n == 0 was bedeutet, dass x/n und der Wert der Erinnerung als Ergebnis genommen und mit Null verglichen werden.

beispiel: 4/5 == 0

4/5 Erinnerung ist 1

1 == 0 (falsch)

0
Hemant