Would this work for your situation?
>>> s = '12abcd405'
>>> result = ''.join([i for i in s if not i.isdigit()])
>>> result
'abcd'
This makes use of a list comprehension, and what is happening here is similar to this structure:
no_digits = []
# Iterate through the string, adding non-numbers to the no_digits list
for i in s:
if not i.isdigit():
no_digits.append(i)
# Now join all elements of the list with '',
# which puts all of the characters together.
result = ''.join(no_digits)
As @AshwiniChaudhary and @KirkStrauser point out, you actually do not need to use the brackets in the one-liner, making the piece inside the parentheses a generator expression (more efficient than a list comprehension). Even if this doesn't fit the requirements for your assignment, it is something you should read about eventually :) :
>>> s = '12abcd405'
>>> result = ''.join(i for i in s if not i.isdigit())
>>> result
'abcd'
Answer from RocketDonkey on Stack OverflowWould this work for your situation?
>>> s = '12abcd405'
>>> result = ''.join([i for i in s if not i.isdigit()])
>>> result
'abcd'
This makes use of a list comprehension, and what is happening here is similar to this structure:
no_digits = []
# Iterate through the string, adding non-numbers to the no_digits list
for i in s:
if not i.isdigit():
no_digits.append(i)
# Now join all elements of the list with '',
# which puts all of the characters together.
result = ''.join(no_digits)
As @AshwiniChaudhary and @KirkStrauser point out, you actually do not need to use the brackets in the one-liner, making the piece inside the parentheses a generator expression (more efficient than a list comprehension). Even if this doesn't fit the requirements for your assignment, it is something you should read about eventually :) :
>>> s = '12abcd405'
>>> result = ''.join(i for i in s if not i.isdigit())
>>> result
'abcd'
And, just to throw it in the mix, is the oft-forgotten str.translate which will work a lot faster than looping/regular expressions:
For Python 2:
from string import digits
s = 'abc123def456ghi789zero0'
res = s.translate(None, digits)
# 'abcdefghizero'
For Python 3:
from string import digits
s = 'abc123def456ghi789zero0'
remove_digits = str.maketrans('', '', digits)
res = s.translate(remove_digits)
# 'abcdefghizero'
Remove all numbers in a list below a value
remove numbers string python - Stack Overflow
string - Remove a digit from a number(integer) in python - Stack Overflow
How to remove a single number from input number in python - Stack Overflow
I have this code:
list = [1,2,3,4,5,6,7,8,9]
for x in list:
if x<5:
list.remove(x)
listBut it returns [2,4,6,7,8,9] instead of [5,6,7,8,9]
Why does it do this and how do I fix it?
UPDATE: It seems to be counterintuitive, but string-based solution is much faster then int-based. Here're my code and results in seconds for 103-, 226-digit and 472-digit numbers. I decided not to test 102139-digit number on my laptop :)
import timeit, math
digits = [100, 200, 500, 1_000, 2_000, 5_000, 10_000, 50_000, 100_000]
def print_str(n):
s = str(n)
for i in range(len(s)):
#print(i)
n2 = int(s[:i] + s[i+1:])
def print_int(a):
p = 1
while p <= a:
n2 = a//p//10*p + a%p
p *= 10
if __name__ == '__main__':
number = 1
for i in digits:
n = 17**math.ceil(math.log(10**i, 17))
str_ = timeit.timeit('print_str(n)', setup='from __main__ import print_str, n', number=number)
int_ = timeit.timeit('print_int(n)', setup='from __main__ import print_int, n', number=number)
print("{:8d}\t{:15.6f}\t{:15.6f}".format(len(str(n)), str_/number*1000, int_/number*1000))
Results (in milliseconds for particular number length):
$ time python3 main.py
101 0.169280 0.185082
201 0.502591 0.537000
501 3.917680 3.195815
1001 13.768999 22.781801
2001 114.404890 120.546628
5001 1066.541904 1625.172070
10002 8033.144731 8802.031382
50001 937385.167088 1045865.986814
100002 7800950.456252 8189620.010314
First column - number of digits, second one - time in milliseconds for the str-based solution, and third - for the int-based.
But how is it possible?
It could be understood if we remember how endless integer numbers are constructed in Python. Under the hood there's an array of 15- or 30-bit integers which being joined produces the result number. So when you divide this number you have to walk through the whole array and modify every every digit. Also take in account complexity - sometimes you have to add or subtract from more significant digit, that complicates process.
When you use strings, you only copy bytes from one place to another. It's extremely fast procedure made with internal cpu instruction.
But what if we do not need conversion to int? For example, we want to print a number, so having it in a string form is better? How will it enfaster process?
Here're results - also in ms for different length
$ time python3 main.py
101 0.051510 0.124668
201 0.091741 0.442547
501 0.357862 2.562110
1001 0.787016 15.229156
2001 2.545076 111.917518
5001 4.993472 1334.944235
UPD: Bencharks of updated versions:
$ time python3 main2.py
digits str1 str2 int1 int2
101 0.047 0.101 0.110 0.073
201 0.091 0.315 0.380 0.145
501 0.338 2.049 2.540 0.778
1001 1.342 16.878 16.032 1.621
2001 1.626 85.277 97.809 5.553
5001 4.903 1039.889 1326.481 32.490
10002 15.987 7856.753 9512.209 129.280
20001 72.205 60363.860 68219.334 487.088
real 2m29.403s
user 2m27.902s
sys 0m0.577s
Another answer producing integers, much faster at that than my other answer and the OP's string solution:
>>> a = 12345
>>> digits = [0] + list(map(int, str(a)))
>>> p = 10**(len(digits) - 2)
>>> for x, y in zip(digits, digits[1:]):
a += (x - y) * p
p //= 10
print(a)
2345
1345
1245
1235
1234
This goes from 2345 to 1345 by replacing the 2 with the 1, which it does by subtracting 2โ 1000 and adding 1โ 1000. Or in short, by adding (1-2)โ 1000. Then it goes from 1345 to 1245 by adding (2-3)โ 100. And so on.
Benchmark results, using a modified version of Eugene's program:
digits str1 str2 int1 int2
101 0.085 0.255 0.376 0.157
201 0.161 0.943 1.569 0.389
501 0.514 9.180 9.932 0.983
1001 0.699 30.544 39.796 2.218
2001 1.402 203.429 291.006 8.435
5001 4.852 2691.292 3983.420 50.616
10002 16.080 21139.318 29114.274 197.343
20001 54.884 167641.593 222848.841 789.182
str1 is the time for the OP's string solution, producing strings.
str2 is the time for the OP's string solution, turning the strings into ints.
int1 is my other solution producing ints.
int2 is my new solution producing ints.
No surprise that the OP's string solution is the fastest overall. Its runtime complexity is quadratic in the number of digits. Which is the total output size, so that's optimal. My new solution is quadratic as well, but doing calculations is of course more work than pure copying.
For producing ints, my new solution is by far the fastest. My old one and the OP's have cubic runtime for that (with the OP's apparently being around 1.4 times as fast as my old one).
The benchmark program (modified version of Eugene's):
import timeit, math
digits = [100, 200, 500, 1_000, 2_000, 5_000, 10_000, 20_000]
def print_str_1(n):
s = str(n)
for i in range(len(s)):
#print(i)
n2 = s[:i] + s[i+1:]
def print_str_2(n):
s = str(n)
for i in range(len(s)):
#print(i)
n2 = int(s[:i] + s[i+1:])
def print_int_1(a):
p = 1
while p <= a:
n2 = a//p//10*p + a%p
p *= 10
def print_int_2(a):
digits = [0] + list(map(int, str(a)))
p = 10**(len(digits) - 2)
for x, y in zip(digits, digits[1:]):
a += (x - y) * p
p //= 10
#print(a)
if __name__ == '__main__':
print(("{:>6}" + 4 * "{:>12}").format('digits', 'str1', 'str2', 'int1', 'int2'))
number = 1
for i in digits:
n = 17**math.ceil(math.log(10**i, 17))
str1 = timeit.timeit('print_str_1(n)', setup='from __main__ import print_str_1, n', number=number)
str2 = timeit.timeit('print_str_2(n)', setup='from __main__ import print_str_2, n', number=number)
int1 = timeit.timeit('print_int_1(n)', setup='from __main__ import print_int_1, n', number=number)
int2 = timeit.timeit('print_int_2(n)', setup='from __main__ import print_int_2, n', number=number)
print(("{:6d}" + 4 * "{:12.3f}").format(len(str(n)), *(x/number*1000 for x in (str1, str2, int1, int2))))
If those are proper numbers, then x // 10 (integer division by 10) should do the trick. If they are strings, then x[:-1] gets rid of the last character. In both cases x is the variable holding the original value.
You may simply divide by 10 and then cast to integer:
inp = [555, 5455, 6555, 3675]
output = [int(x / 10) for x in inp]
print(output) # [55, 545, 655, 367]
The above works if your inputs are actual numbers, and not strings. If the inputs are not strings, then you certainly should not convert them to string first, since the above will perform much faster than a bulky string operation.