I want to get the first two nonzero digits of a float number using math library.
for example for
x = 1.27
the answer would be
12
and for
x = 0.025
the answer would be
25
I could find the first and second nonzero number:
a = str(x)
o1 = int(a.replace('0', '')[1])
o2 = int(a.replace('0', '')[2])
and then I can concat them but I get
string index out of range
error for big numbers.
Here's one approach:
from itertools import islice
def first_n_nonzero_digits(l, n):
return ''.join(islice((i for i in str(l) if i not in {'0', '.'}), n))
first_n_nonzero_digits(1.27, 2)
# '12'
first_n_nonzero_digits(0.025, 2)
# '25'
Here's one without any imports and using sorted:
def first_n_nonzero_digits_v2(l, n):
return ''.join(sorted(str(x), key=lambda x: x in {'0', '.'}))[:2]
first_n_nonzero_digits_v2(1.27, 2)
# '12'
first_n_nonzero_digits_v2(0.025, 2)
# '25'
Here is a simple solution:
str(x).replace(".","").replace("0", "")[:2]
Try this:
def nonzeroDigits(f,n=2):
counter = 1
s = str(f).replace(".","")
for ndx,i in enumerate(s):
if i == "0":
counter = 1
continue
if counter >= n:
return s[ndx - n + 1: ndx + 1]
counter += 1
raise ValueError("Doesn't have non-zero consecutive Digits")
I have tired to make it as simple as possible without using any third-party library.
print(nonzeroDigits(1.27))
# print(nonzeroDigits(1.02)) # Raise ValueError Exception
print(nonzeroDigits(0.025))
Returns:
12
25
Related
Given string str containing alphanumeric characters. The task is to calculate the sum of all the numbers present in the string.
Example 1:
Input:
str = 1abc23
Output: 24
Explanation: 1 and 23 are numbers in the
a string which is added to get the sum as
24.
Example 2:
Input:
str = geeks4geeks
Output: 4
Explanation: 4 is the only number, so the
the sum is 4.
I broke down the problem into smaller parts, for first I just want to extract the numbers.
s = "a12bc3d"
number = ""
for i in range(0, len(s)):
if s[i].isdigit():
n=0
number = number + s[i]
while s[i].isdigit():
n = n+1
if s[i + n].isdigit():
number = number + s[i+n] + " "
else:
break
i = i + n + 1
else:
continue
print(number)
my output from the above code is 12 23 but it should be 12 3, as the for loop is starting from the initial point making 2 coming twice, I have tried to move the for loop forward by updating i = i + n + 1 but it's not working out like that.
It will be great if someone gives me a direction, any help is really appreciated.
A slightly simpler approach with regex:
import re
numbers_sum = sum(int(match) for match in re.findall(r'(\d+)', s))
Use itertools.groupby to break the string into groups of digits and not-digits; then convert the digit groups to int and sum them:
>>> from itertools import groupby
>>> def sum_numbers(s: str) -> int:
... return sum(int(''.join(g)) for d, g in groupby(s, str.isdigit) if d)
...
>>> sum_numbers("1abc23")
24
>>> sum_numbers("geeks4geeks")
4
you can use regex.
import re
s='a12bc3d'
sections = re.split('(\d+)',s)
numeric_sections = [int(x) for x in sections if x.isdigit()]
sum_ = sum(numeric_sections)
print(sum_)
I appreciate the solutions with regex and group-by. And I got the solution using logic as well.
`s = "4a7312cfh86"
slist = [i for i in s]
nlist = []
for i in range(len(slist)):
if slist[i].isdigit() and (i != (len(slist) - 1)):
if not slist[i + 1].isdigit():
nlist.append(slist[i])
else:
slist[i + 1] = slist[i] + slist[i + 1]
elif slist[i].isdigit() and (i == (len(slist) - 1)):
nlist.append(slist[i])
def addingElement(arr):
if len(arr) == 0:
return 0
return addingElement(arr[1:]) + int(arr[0])
print(addingElement(nlist))
Output - 7402
when given a string. how to extract the biggest numeric substring without regex?
if for example given a string: 24some555rrr444
555 will be the biggest substring
def maximum(s1)
sub=[]
max=0
for x in s1
if x.isnummeric() and x>max
sub.append(x)
max=x
return max
what to do in order this code to work?
Thank you in advance!
Replace all non digits to a space, split the resulting word based on spaces, convert each number to a int and then find the max of them
>>> s = '24some555rrr444'
>>> max(map(int, ''.join(c if c.isdigit() else ' ' for c in s).split()))
555
You could use itertools.groupby to pull out the digits in groups and find the max:
from itertools import groupby
s = "24some555rrr444"
max(int(''.join(g)) for k, g in groupby(s, key=str.isdigit) if k)
# 555
Not using regex is wierd, but ok
s = "24some555rrr444"
n = len(s)
m = 0
for i in range(n):
for len in range(i + 1, n + 1):
try:
v = int(s[i:len])
m = v if v > m else m
except:
pass
print(m)
Or if want really want to compress it to basically one line (except the convert function), you can use
s = "24some555rrr444"
n = len(s)
def convert(s):
try:
return int(s)
except:
return -1
m = max(convert(s[i:l]) for i in range(n) for l in range(i + 1, n + 1))
print(m)
In order to stay in your mindset, i propose this, it is quite close from the initial demand:
#Picked a random number+string stringchain
OriginalStringChain="123245hjkh2313k313j23b"
#Creation of the list which will contain the numbers extracted from the formerly chosen stringchain
resultstable=[]
#The b variable will contain the extracted numbers as a string chain
b=""
for i,j in zip(OriginalStringChain, range(len(OriginalStringChain))):
c= j+1
#the is.digit() fonction is your sql isnumeric equivalent in python
#this bloc of if will extract numbers one by one and concatenate them, if they are several in a row, in a string chain of numbers before adding them in the resultstable
if i.isdigit() == True:
b+=i
if j < len(OriginalStringChain)-1 and OriginalStringChain[c].isdigit() == False:
resutstable.append(int(b))
elif j== len(OriginalStringChain)-1 and OriginalStringChain[j].isdigit() == True:
resultstable.append(int(b))
else:
b=""
print(resultstable)
#At the end, you just obtain a list where every values are the numbers we extracted previously and u just use the max function
print(max(resultstable))
I hope i was clear.
Cheers
if i just read my sum_digits function here, it makes sense in my head but it seems to be producing wrong results. Any tip?
def is_a_digit(s):
''' (str) -> bool
Precondition: len(s) == 1
Return True iff s is a string containing a single digit character (between
'0' and '9' inclusive).
>>> is_a_digit('7')
True
>>> is_a_digit('b')
False
'''
return '0' <= s and s <= '9'
def sum_digits(digit):
b = 0
for a in digit:
if is_a_digit(a) == True:
b = int(a)
b += 1
return b
For the function sum_digits, if i input sum_digits('hihello153john'), it should produce 9
Notice that you can easily solve this problem using built-in functions. This is a more idiomatic and efficient solution:
def sum_digits(digit):
return sum(int(x) for x in digit if x.isdigit())
print(sum_digits('hihello153john'))
=> 9
In particular, be aware that the is_a_digit() method already exists for string types, it's called isdigit().
And the whole loop in the sum_digits() function can be expressed more concisely using a generator expression as a parameter for the sum() built-in function, as shown above.
You're resetting the value of b on each iteration, if a is a digit.
Perhaps you want:
b += int(a)
Instead of:
b = int(a)
b += 1
Another way of using built in functions, is using the reduce function:
>>> numeric = lambda x: int(x) if x.isdigit() else 0
>>> reduce(lambda x, y: x + numeric(y), 'hihello153john', 0)
9
One liner
sum_digits = lambda x: sum(int(y) for y in x if y.isdigit())
I would like to propose a different solution using regx that covers two scenarios:
1.
Input = 'abcd45def05'
Output = 45 + 05 = 50
import re
print(sum(int(x) for x in re.findall(r'[0-9]+', my_str)))
Notice the '+' for one or more occurrences
2.
Input = 'abcd45def05'
Output = 4 + 5 + 0 + 5 = 14
import re
print(sum(int(x) for x in re.findall(r'[0-9]', my_str)))
Another way of doing it:
def digit_sum(n):
new_n = str(n)
sum = 0
for i in new_n:
sum += int(i)
return sum
An equivalent for your code, using list comprehensions:
def sum_digits(your_string):
return sum(int(x) for x in your_string if '0' <= x <= '9')
It will run faster then a "for" version, and saves a lot of code.
Just a variation to #oscar's answer, if we need the sum to be single digit,
def sum_digits(digit):
s = sum(int(x) for x in str(digit) if x.isdigit())
if len(str(s)) > 1:
return sum_digits(s)
else:
return s
#if string =he15ll15oo10
#sum of number =15+15+10=40
def sum_of_all_Number(s):
num = 0
sum = 0
for i in s:
if i.isdigit():
num = num * 10 + int(i)
else:
sum = sum + num
num = 0
return sum+num
#if string =he15ll15oo10
#sum of digit=1+5+1+5+1+0=13
def sum_of_Digit(s):
sum = 0
for i in s:
if i.isdigit():
sum= sum + int(i)
return sum
s = input("Enter any String ")
print("Sum of Number =", sum_of_all_Number(s))
print("Sum Of Digit =", sum_of_Digit(s))
simply turn the input to integer by int(a) ---> using a.isdigit to make sure the input not None ('') ,
if the input none make it 0 and return sum of the inputs in a string simply
def sum_str(a, b):
a = int(a) if a.isdigit() else 0
b = int(b) if b.isdigit() else 0
return f'{a+b}'
I need to join the elements in a list without using the join command, so if for example I have the list:
[12,4,15,11]
The output should be:
1241511
Here is my code so far:
def lists(list1):
answer = 0
h = len(list1)
while list1 != []:
answer = answer + list1[0] * 10 ** h
h = h - 1
list1.pop(0)
print(answer)
But, in the end, the answer ends up being 125610 which is clearly wrong.
I think the logic is OK, but I can't find the problem?
If you just want to print the number rather than return an actual int:
>>> a = [12,4,15,11]
>>> print(*a, sep='')
1241511
You could just convert each element to a string, add them, and then convert back to an int:
def lists(list1):
answer=''
for number in list1:
answer+=str(number)
print(int(answer))
lists([12,4,15,11])
>>>
1241511
s = ""
for x in map(str, x):
s += x
print(s)
1241511
There can be few more options like
Option1
>>> lst=[12,4,15,11]
>>> str(lst).translate(None, '[,] ')
'1241511'
Option 2
>>> join = lambda e: str(e[0]) + join(e[1:]) if e else ""
>>> join(lst)
'1241511'
Option 3
>>> ("{}"*len(lst)).format(*lst)
'1241511'
Option 4
>>> reduce(lambda a,b:a+b,map(str,lst))
'1241511'
a numeric solution, using your code
import math
def numdig(n):
#only positive numbers
if n > 0:
return int(math.log10(n))+1
else:
return 1
def lists(list1):
answer = 0
h = 0
while list1 != []:
answer = answer * 10 ** h + list1[0]
list1.pop(0)
if list1 != []:
h = numdig(list1[0])
print(answer)
lists([12,4,15,11])
You may try map and reduce with lambda like this:
def without_join(alist):
try:
return int(reduce(lambda a,b: a + b, map(str, alist)))
except ValueError, error:
print error
return None
print without_join([12,4,15,11])
Here's an entirely numerical solution, playing off of your notion of messing with powers of 10. You were on the right track, but your implementation assumed all values were 1 digit long.
import math
def lists(list1):
b = 0
foo = 0
for item in reversed(list1):
b += item*(10**foo)
foo += int(math.floor(math.log10(item))) + 1
return b
a = [12, 4, 15, 11]
print lists(a)
This returns 1241511, as requested.
All I'm doing here is looping through the list in reverse order and keeping track of how many digits to the left I need to shift each value. This allows integers with an arbitrary number of digits.
list_name_of_program = [a,b,c,d,e,f]
program = ""
for pro in list_name_of_program:
program += str(pro)
program += "," # you can use seprator a space " " or different
print(program[:-1])
Output:
'a,b,c,d,e,f'
if i just read my sum_digits function here, it makes sense in my head but it seems to be producing wrong results. Any tip?
def is_a_digit(s):
''' (str) -> bool
Precondition: len(s) == 1
Return True iff s is a string containing a single digit character (between
'0' and '9' inclusive).
>>> is_a_digit('7')
True
>>> is_a_digit('b')
False
'''
return '0' <= s and s <= '9'
def sum_digits(digit):
b = 0
for a in digit:
if is_a_digit(a) == True:
b = int(a)
b += 1
return b
For the function sum_digits, if i input sum_digits('hihello153john'), it should produce 9
Notice that you can easily solve this problem using built-in functions. This is a more idiomatic and efficient solution:
def sum_digits(digit):
return sum(int(x) for x in digit if x.isdigit())
print(sum_digits('hihello153john'))
=> 9
In particular, be aware that the is_a_digit() method already exists for string types, it's called isdigit().
And the whole loop in the sum_digits() function can be expressed more concisely using a generator expression as a parameter for the sum() built-in function, as shown above.
You're resetting the value of b on each iteration, if a is a digit.
Perhaps you want:
b += int(a)
Instead of:
b = int(a)
b += 1
Another way of using built in functions, is using the reduce function:
>>> numeric = lambda x: int(x) if x.isdigit() else 0
>>> reduce(lambda x, y: x + numeric(y), 'hihello153john', 0)
9
One liner
sum_digits = lambda x: sum(int(y) for y in x if y.isdigit())
I would like to propose a different solution using regx that covers two scenarios:
1.
Input = 'abcd45def05'
Output = 45 + 05 = 50
import re
print(sum(int(x) for x in re.findall(r'[0-9]+', my_str)))
Notice the '+' for one or more occurrences
2.
Input = 'abcd45def05'
Output = 4 + 5 + 0 + 5 = 14
import re
print(sum(int(x) for x in re.findall(r'[0-9]', my_str)))
Another way of doing it:
def digit_sum(n):
new_n = str(n)
sum = 0
for i in new_n:
sum += int(i)
return sum
An equivalent for your code, using list comprehensions:
def sum_digits(your_string):
return sum(int(x) for x in your_string if '0' <= x <= '9')
It will run faster then a "for" version, and saves a lot of code.
Just a variation to #oscar's answer, if we need the sum to be single digit,
def sum_digits(digit):
s = sum(int(x) for x in str(digit) if x.isdigit())
if len(str(s)) > 1:
return sum_digits(s)
else:
return s
#if string =he15ll15oo10
#sum of number =15+15+10=40
def sum_of_all_Number(s):
num = 0
sum = 0
for i in s:
if i.isdigit():
num = num * 10 + int(i)
else:
sum = sum + num
num = 0
return sum+num
#if string =he15ll15oo10
#sum of digit=1+5+1+5+1+0=13
def sum_of_Digit(s):
sum = 0
for i in s:
if i.isdigit():
sum= sum + int(i)
return sum
s = input("Enter any String ")
print("Sum of Number =", sum_of_all_Number(s))
print("Sum Of Digit =", sum_of_Digit(s))
simply turn the input to integer by int(a) ---> using a.isdigit to make sure the input not None ('') ,
if the input none make it 0 and return sum of the inputs in a string simply
def sum_str(a, b):
a = int(a) if a.isdigit() else 0
b = int(b) if b.isdigit() else 0
return f'{a+b}'