webentwicklung-frage-antwort-db.com.de

Teilen Sie eine ganze Zahl in Ziffern, um eine ISBN-Prüfsumme zu berechnen

Ich schreibe ein Programm, das die Prüfziffer einer ISBN-Nummer berechnet. Ich muss die Eingabe des Benutzers (neun Ziffern einer ISBN) in eine Ganzzahlvariable einlesen und dann die letzte Ziffer mit 2, die vorletzte Ziffer mit 3 usw. multiplizieren. Wie kann ich die ganze Zahl in ihre konstituierenden Ziffern "aufteilen", um dies zu tun? Da dies eine grundlegende Hausaufgabe ist, darf ich keine Liste verwenden.

50
zequzd

Erstellen Sie einfach eine Zeichenfolge daraus.

myinteger = 212345
number_string = str(myinteger)

Das ist genug. Jetzt können Sie darüber iterieren:

for ch in number_string:
    print ch # will print each digit in order

Oder du kannst es schneiden:

print number_string[:2] # first two digits
print number_string[-3:] # last three digits
print number_string[3] # forth digit

Oder besser, konvertieren Sie die Eingabe des Benutzers nicht in eine Ganzzahl (der Benutzer gibt eine Zeichenfolge ein).

isbn = raw_input()
for pos, ch in enumerate(reversed(isbn)):
    print "%d * %d is %d" % pos + 2, int(ch), int(ch) * (pos + 2)

Weitere Informationen finden Sie in einem Tutorial .

80
nosklo
while number:
    digit = number % 10

    # do whatever with digit

    # remove last digit from number (as integer)
    number //= 10

Bei jeder Wiederholung der Schleife wird die letzte Ziffer aus der Zahl entfernt und digit zugewiesen. Es ist umgekehrt, beginnt mit der letzten Ziffer und endet mit der ersten Ziffer

66
list_of_ints = [int(i) for i in str(ISBN)]

Gibt dir eine geordnete Liste von Ints. Natürlich können Sie bei der Eingabe von Ente genauso gut mit str (ISBN) arbeiten.

Bearbeiten: Wie in den Kommentaren erwähnt, ist diese Liste nicht im Sinne von auf- oder absteigend sortiert, sie hat jedoch eine definierte Reihenfolge (Mengen, Wörterbücher usw.) in Python theoretisch nicht, obwohl in der Praxis die Reihenfolge dazu neigt ziemlich zuverlässig sein). Wenn Sie es sortieren möchten:

list_of_ints.sort ()

ist dein Freund. Beachten Sie, dass sort () an Ort und Stelle sortiert wird (wie in, ändert tatsächlich die Reihenfolge der vorhandenen Liste) und gibt keine neue Liste zurück.

20
mavnn

Bei älteren Versionen von Python ...

map(int,str(123))

Bei der neuen Version 3k

list(map(int,str(123)))
13
st0le
(number/10**x)%10

Sie können dies in einer Schleife verwenden, wobei Zahl die vollständige Zahl ist, x jede Iteration der Schleife (0,1,2,3, ..., n), wobei n der Stopppunkt ist. x = 0 gibt Einsen an, x = 1 ergibt Zehnerstellen, x = 2 gibt Hunderte an und so weiter. Beachten Sie, dass dies den Wert der Ziffern von rechts nach links angibt. Dies ist möglicherweise nicht für eine ISBN gedacht, aber es wird immer noch jede Ziffer isoliert.

3
Pski17

Die Konvertierung in str ist definitiv langsamer als die Division durch 10.

map ist etwas langsamer als das Listenverständnis:

convert to string with map 2.13599181175
convert to string with list comprehension 1.92812991142
modulo, division, recursive 0.948769807816
modulo, division 0.699964046478

Diese Zeiten wurden durch den folgenden Code auf meinem Laptop zurückgegeben:

foo = """\
def foo(limit):
    return sorted(set(map(sum, map(lambda x: map(int, list(str(x))), map(lambda x: x * 9, range(limit))))))

foo(%i)
"""

bar = """\
def bar(limit):
    return sorted(set([sum([int(i) for i in str(n)]) for n in [k *9 for k in range(limit)]]))

bar(%i)
"""

rac = """\
def digits(n):
    return [n] if n<10 else digits(n / 10)+[n %% 10]

def rabbit(limit):
    return sorted(set([sum(digits(n)) for n in [k *9 for k in range(limit)]]))

rabbit(%i)
"""

rab = """\
def sum_digits(number):
  result = 0
  while number:
    digit = number %% 10
    result += digit
    number /= 10
  return result

def rabbit(limit):
    return sorted(set([sum_digits(n) for n in [k *9 for k in range(limit)]]))

rabbit(%i)
"""


import timeit

print "convert to string with map", timeit.timeit(foo % 100, number=10000)
print "convert to string with list comprehension", timeit.timeit(bar % 100, number=10000)
print "modulo, division, recursive", timeit.timeit(rac % 100, number=10000)
print "modulo, division", timeit.timeit(rab % 100, number=10000)
2
bpgergo

Rekursionsversion:

def int_digits(n):
    return [n] if n<10 else int_digits(n/10)+[n%10]
2
chyanog

Konvertieren Sie ihn in einen String und ordnen Sie ihn mit der Funktion int () zu.

map(int, str(1231231231))
2
Evgeny

Verwenden Sie den Rumpf dieser Schleife, um mit den Ziffern das zu tun, was Sie möchten

for digit in map(int, str(my_number)):
1
shadowfox

Ähnlich wie diese Antwort, aber mehr ein "Pythonic" Weg, um über die Digis zu iterieren, wäre:

while number:
    # "pop" the rightmost digit
    number, digit = divmod(number, 10)
1
Jeremy Cantrell

Ich habe dieses Programm erstellt und hier ist der Code, der tatsächlich die Prüfziffer in meinem Programm berechnet

    #Get the 10 digit number
    number=input("Please enter ISBN number: ")

    #Explained below
    no11 = (((int(number[0])*11) + (int(number[1])*10) + (int(number[2])*9) + (int(number[3])*8) 
           + (int(number[4])*7) + (int(number[5])*6) + (int(number[6])*5) + (int(number[7])*4) +
           (int(number[8])*3) + (int(number[9])*2))/11)

    #Round to 1 dp
    no11 = round(no11, 1)

    #explained below
    no11 = str(no11).split(".")

    #get the remainder and check digit
    remainder = no11[1]
    no11 = (11 - int(remainder))

    #Calculate 11 digit ISBN
    print("Correct ISBN number is " + number + str(no11))

Es ist eine lange Codezeile, aber sie teilt die Zahl auf, multipliziert die Ziffern mit dem entsprechenden Betrag, addiert sie und teilt sie mit 11 in einer Codezeile. Mit der Funktion .split () wird nur eine Liste erstellt (wobei die Dezimalstelle aufgeteilt wird), sodass Sie das zweite Element in der Liste nehmen und die Zahl von 11 zur Ermittlung der Prüfziffer verwenden können. Dies könnte auch durch die Änderung dieser beiden Linien noch effizienter gestaltet werden:

    remainder = no11[1]
    no11 = (11 - int(remainder))

Zu diesem:

    no11 = (11 - int(no11[1]))

Hoffe das hilft :)

1
Ben

Angenommen, Sie möchten die i - -te niedrigstwertige Ziffer von einer Ganzzahl x erhalten, können Sie Folgendes versuchen:

(abs(x)%(10**i))/(10**(i-1))

Ich hoffe, es hilft.

0
Ricardo Alejos

Nach eigenen sorgfältigen Recherchen fand ich verschiedene Lösungen, bei denen jede Vor- und Nachteile hat. Verwenden Sie das für Ihre Aufgabe am besten geeignete.

Alle Beispiele wurden mit dem CPython 3.5 auf dem Betriebssystem GNU/Linux Debian 8 getestet.


Rekursion verwenden

Code

def get_digits_from_left_to_right(number, lst=None):
    """Return digits of an integer excluding the sign."""

    if lst is None:
        lst = list()

    number = abs(number)

    if number < 10:
        lst.append(number)
        return Tuple(lst)

    get_digits_from_left_to_right(number // 10, lst)
    lst.append(number % 10)

    return Tuple(lst)

Demo

In [121]: get_digits_from_left_to_right(-64517643246567536423)
Out[121]: (6, 4, 5, 1, 7, 6, 4, 3, 2, 4, 6, 5, 6, 7, 5, 3, 6, 4, 2, 3)

In [122]: get_digits_from_left_to_right(0)
Out[122]: (0,)

In [123]: get_digits_from_left_to_right(123012312312321312312312)
Out[123]: (1, 2, 3, 0, 1, 2, 3, 1, 2, 3, 1, 2, 3, 2, 1, 3, 1, 2, 3, 1, 2, 3, 1, 2)

Verwendung der Funktion divmod

Code

def get_digits_from_right_to_left(number):
    """Return digits of an integer excluding the sign."""

    number = abs(number)

    if number < 10:
        return (number, )

    lst = list()

    while number:
        number, digit = divmod(number, 10)
        lst.insert(0, digit)

    return Tuple(lst)

Demo

In [125]: get_digits_from_right_to_left(-3245214012321021213)
Out[125]: (3, 2, 4, 5, 2, 1, 4, 0, 1, 2, 3, 2, 1, 0, 2, 1, 2, 1, 3)

In [126]: get_digits_from_right_to_left(0)
Out[126]: (0,)

In [127]: get_digits_from_right_to_left(9999999999999999)
Out[127]: (9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9)

Verwendung einer Konstruktion Tuple(map(int, str(abs(number)))

In [109]: Tuple(map(int, str(abs(-123123123))))
Out[109]: (1, 2, 3, 1, 2, 3, 1, 2, 3)

In [110]: Tuple(map(int, str(abs(1412421321312))))
Out[110]: (1, 4, 1, 2, 4, 2, 1, 3, 2, 1, 3, 1, 2)

In [111]: Tuple(map(int, str(abs(0))))
Out[111]: (0,)

Verwendung der Funktion re.findall

In [112]: Tuple(map(int, re.findall(r'\d', str(1321321312))))
Out[112]: (1, 3, 2, 1, 3, 2, 1, 3, 1, 2)

In [113]: Tuple(map(int, re.findall(r'\d', str(-1321321312))))
Out[113]: (1, 3, 2, 1, 3, 2, 1, 3, 1, 2)

In [114]: Tuple(map(int, re.findall(r'\d', str(0))))
Out[114]: (0,)

Verwendung des Moduls decimal

In [117]: decimal.Decimal(0).as_Tuple().digits
Out[117]: (0,)

In [118]: decimal.Decimal(3441120391321).as_Tuple().digits
Out[118]: (3, 4, 4, 1, 1, 2, 0, 3, 9, 1, 3, 2, 1)

In [119]: decimal.Decimal(-3441120391321).as_Tuple().digits
Out[119]: (3, 4, 4, 1, 1, 2, 0, 3, 9, 1, 3, 2, 1)
0
Seti Volkylany

Antwort: 165

Methode: rohe Gewalt! Hier ist ein kleines bisschen Python-Code (Version 2.7), um alles zu zählen.

from math import sqrt, floor
is_ps = lambda x: floor(sqrt(x)) ** 2 == x
count = 0
for n in range(1002, 10000, 3):
    if n % 11 and is_ps(sum(map(int, str(n)))):
        count += 1
        print "#%i: %s" % (count, n)
0
dohmatob

Wie wäre es mit einer Einzeilenliste von Ziffern ...

ldigits = lambda n, l=[]: not n and l or l.insert(0,n%10) or ldigits(n/10,l)
0
Lord British