web-dev-qa-db-fra.com

Fractionner un entier en chiffres pour calculer une somme de contrôle ISBN

J'écris un programme qui calcule le chiffre de contrôle d'un numéro ISBN. Je dois lire les entrées de l'utilisateur (neuf chiffres d'un ISBN) dans une variable entière, puis multiplier le dernier chiffre par 2, le dernier dernier chiffre par 3, etc. Comment puis-je "scinder" l'entier en ses chiffres constitutifs pour le faire? Comme il s’agit d’un exercice de devoirs élémentaire, je ne suis pas censé utiliser une liste.

50
zequzd

Créez simplement une chaîne en dehors de celle-ci.

myinteger = 212345
number_string = str(myinteger)

C'est assez. Maintenant, vous pouvez le parcourir:

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

Ou vous pouvez le trancher:

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

Ou mieux, ne convertissez pas l'entrée de l'utilisateur en entier (l'utilisateur tape une chaîne)

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

Pour plus d'informations, lisez un tutorial .

80
nosklo
while number:
    digit = number % 10

    # do whatever with digit

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

A chaque itération de la boucle, il supprime le dernier chiffre du numéro en lui attribuant la valeur digit. En sens inverse, commence par le dernier chiffre et finit par le premier

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

Vous donnera une liste ordonnée d'ints. Bien sûr, avec une frappe de canard, vous pouvez aussi bien utiliser str (ISBN).

Edit: Comme mentionné dans les commentaires, cette liste n’est pas triée par ordre croissant ou décroissant, mais elle a un ordre défini (ensembles, dictionnaires, etc. en python, en théorie, pas être assez fiable). Si vous voulez le trier:

list_of_ints.sort ()

est votre ami. Notez que sort () trie sur place (comme dans, modifie réellement l'ordre de la liste existante) et ne renvoie pas une nouvelle liste.

20
mavnn

Sur les anciennes versions de Python ...

map(int,str(123))

Sur la nouvelle version 3k

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

Vous pouvez l'utiliser dans une boucle, où nombre est le nombre entier, x chaque itération de la boucle (0,1,2,3, ..., n), n étant le point d'arrêt. x = 0 donne la place aux unités, x = 1 donne les dizaines, x = 2 donne les centaines, et ainsi de suite. Gardez à l’esprit que cela donnera la valeur des chiffres de droite à gauche, il ne s’agit donc peut-être pas d’un ISBN, mais il isolera toujours chaque chiffre.

3
Pski17

La conversion en str est nettement plus lente que la division par 10.

map est un peu plus lent que la compréhension de la liste:

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

Ces temps ont été retournés par le code suivant sur mon ordinateur portable:

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

Version récursive:

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

Convertissez-le en chaîne et mappez-le dessus avec la fonction int ().

map(int, str(1231231231))
2
Evgeny

Utilisez le corps de cette boucle pour faire ce que vous voulez avec les chiffres

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

Semblable à ceci réponse mais plus un moyen plus "pythonique" de parcourir le digis serait:

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

J'ai créé ce programme et voici le bit de code qui calcule le chiffre de contrôle dans mon programme

    #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))

C'est une longue ligne de code, mais elle divise le nombre, multiplie les chiffres par la quantité appropriée, les additionne et les divise par 11, en une seule ligne de code. La fonction .split () crée simplement une liste (divisée à la décimale) afin que vous puissiez prendre le deuxième élément de la liste et le prendre à partir de 11 pour trouver le chiffre de contrôle. Cela pourrait également être rendu encore plus efficace en modifiant ces deux lignes:

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

Pour ça:

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

J'espère que cela t'aides :)

1
Ben

En supposant que vous souhaitiez obtenir le i - ème chiffre le moins significatif d’un nombre entier x , vous pouvez essayer:

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

J'espère que ça aide.

0
Ricardo Alejos

Après des recherches diligentes, j'ai trouvé plusieurs solutions, chacune présentant des avantages et des inconvénients. Utilisez le plus approprié à votre tâche.

Tous les exemples testés avec CPython 3.5 sur le système d’exploitation GNU/Linux Debian 8.


Utiliser une récursion

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)

Démo

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)

Utilisation de la fonction 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)

Démo

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)

Utilisation d'une construction 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,)

Utilisation de la fonction 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,)

Utilisation du module 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

Réponse: 165

Méthode: force brute! Voici un petit bout de code Python (version 2.7) pour les compter tous.

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

Que diriez-vous d'une liste de chiffres en une ligne ...

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