47

I want to make a number , for example 43365644 into single numbers [4,3,3....,4,4]

and append it on a list

user3221242
  • 471
  • 1
  • 4
  • 5

4 Answers4

116

This can be done quite easily if you:

  1. Use str to convert the number into a string so that you can iterate over it.

  2. Use a list comprehension to split the string into individual digits.

  3. Use int to convert the digits back into integers.

Below is a demonstration:

>>> n = 43365644
>>> [int(d) for d in str(n)]
[4, 3, 3, 6, 5, 6, 4, 4]
>>>
24

Here's a way to do it without turning it into a string first (based on some rudimentary benchmarking, this is about twice as fast as stringifying n first):

>>> n = 43365644
>>> [(n//(10**i))%10 for i in range(math.ceil(math.log(n, 10))-1, -1, -1)]
[4, 3, 3, 6, 5, 6, 4, 4]

Updating this after many years in response to comments of this not working for powers of 10:

[(n//(10**i))%10 for i in range(math.ceil(math.log(n, 10)), -1, -1)][bool(math.log(n,10)%1):]

The issue is that with powers of 10 (and ONLY with these), an extra step is required. ---So we use the remainder in the log_10 to determine whether to remove the leading 0--- We can't exactly use this because floating-point math errors cause this to fail for some powers of 10. So I've decided to cross the unholy river into sin and call upon regex.

In [32]: n = 43

In [33]: [(n//(10**i))%10 for i in range(math.ceil(math.log(n, 10)), -1, -1)][not(re.match('10*', str(n))):]
Out[33]: [4, 3]

In [34]: n = 1000

In [35]: [(n//(10**i))%10 for i in range(math.ceil(math.log(n, 10)), -1, -1)][not(re.match('10*', str(n))):]
Out[35]: [1, 0, 0, 0]
inspectorG4dget
  • 110,290
  • 27
  • 149
  • 241
  • 1
    I guess there is a cross point where calculating an arbitrarily big power of 10 will cost more than parsing a string per each digit. I did not look into this, though :) – Stefano Sanfilippo Jan 21 '14 at 22:40
  • 2
    This is basically what the `str` function has to do internally as well, it doesn't just magically have the string representation. Of course the built-in `str` function is written in C and therefore faster than Python code, but I'm pretty sure the numbers would have to get extremely big for this to be slower than parsing a string as the Python interpreter can heavily optimize list comprehensions. Additionally you could use this as an iterator if you don't really need a list, improving performance further, whereas the `str` function will always build the complete string at a time. – Cu3PO42 Jan 21 '14 at 22:53
  • @Cu3PO42: You do have a point. Perhaps it is the stringification and re-intification that causes the 2x runtime (2 conversions, which are effectively inverses of each other, in some ways). Also, let's not forget that the built-in math is also implemented in C, which should be comparably fast, in context – inspectorG4dget Jan 21 '14 at 23:02
  • Wondering if I'm doing something wrong. Pasting your two lines into a python shell (2.7.10), with an `import math` first, gives me: `TypeError: range() integer start argument expected, got float.` – melwil Dec 08 '17 at 11:20
  • 1
    @melwil: surround that `math.ceil` with an `int(...)` inside the call to `range`. That should fix it – inspectorG4dget Dec 10 '17 at 21:20
  • 10
    This answer gives incorrect results for powers of 10. For example, it returns `[0, 0]` when `n == 100`. – Jack Meister Jan 13 '18 at 22:06
  • 2
    How could be possible to get many upvotes in this answer!? This gives wrong results for any input in the set {1, 10,100, 1000, etc}. – Alexandre V. Oct 31 '20 at 13:22
  • @JackMeister is right, this is not working for powers of 10. I'm trying to resolve myself but I wonder why is it not resolved at all by the poster. – MattSom Feb 22 '21 at 22:19
  • 1
    Updated my answer after 7 years :) Thanks for the feedback, folks! – inspectorG4dget Feb 22 '21 at 22:37
  • @inspectorG4dget Thank you for the update! Sadly it does not work for 1000 now. Works for 1, 10, 100 and 10000. Also not working for 1 million, so every 10**3 steps the leading 1 cuts off. – MattSom Feb 22 '21 at 23:50
  • 1
    @MattSom: Oh! FML! `math.log(1000, 10)` gives 2.99999...8 rather than 3 – inspectorG4dget Feb 22 '21 at 23:53
  • @inspectorG4dget Haha I see. So need the second ceiling func for the additional log func? – MattSom Feb 22 '21 at 23:59
  • @MattSom: can't use a `ceil` to fix that. I've done something dastardly with `re`. Here comes – inspectorG4dget Feb 23 '21 at 00:00
  • @inspectorG4dget I see, I'll try to decipher it to understand. I wonder, is the benchmark still considerably better this way? – MattSom Feb 23 '21 at 00:05
  • @MattSom: I actually wonder if "the correct answer" will end up being `while n: answer.append(n%10); n//=10` – inspectorG4dget Feb 23 '21 at 16:02
14

The easiest way is to turn the int into a string and take each character of the string as an element of your list:

>>> n = 43365644 
>>> digits = [int(x) for x in str(n)]
>>> digits
[4, 3, 3, 6, 5, 6, 4, 4]
>>> lst.extend(digits)  # use the extends method if you want to add the list to another

It involves a casting operation, but it's readable and acceptable if you don't need extreme performance.

heiligbasil
  • 149
  • 3
  • 11
Maxime Lorant
  • 34,607
  • 19
  • 87
  • 97
  • 1
    it does not work with negatives – DAG Mar 01 '20 at 19:15
  • @DAG What could be the expected result for `-123`? `[-1, 2, 3]` or `[1, 2, 3]`? Or even `[-1, -2, -3]`? We could dismiss the minus sign in the string by doing `str(n).strip('-')` but the negative case was not given in the original question. – Maxime Lorant Mar 02 '20 at 14:22
5

If you want to change your number into a list of those numbers, I would first cast it to a string, then casting it to a list will naturally break on each character:

[int(x) for x in str(n)]
Slater Victoroff
  • 21,376
  • 21
  • 85
  • 144