Python - Adding all digits in string - python

How can i create a function that returns the sum of a string made up of 3 or more digits. For example, if the parameter/string is "13456". How can I return the result of (1*3 + 3*4 + 4*5 + 5*6). Thank you, all help is appreciated. Very new to python.

Another one-liner:
a = '13456'
print(sum([int(x)*int(y) for x, y in zip(a[1:], a[:-1])]))

You just need to go through the string, multiplying the actual value to the next value and add it to a variable to return it later.
def func(param):
ret = 0
for i in range(len(param)-1):
ret = ret + int(param[i]) * int(param[i+1])
return ret

my_string = "12345"
total = 0
for n in range(len(my_string) - 1):
total += int(my_string[n]) * int(my_string[n+1])

This function first turns your string into a list and then applies a map on it to convert all the elements to ints. Finally it uses a loop to access and multiply consecutive elements,
def str_sum(nstr):
nint = list(map(int, list(nstr)));
res = 0;
for i in range(len(nint[:-1])):
res += nint[i]*nint[i+1]
return res
Converting result of map into list using list(map(...)) is redundant in Python 2.7 but necessary in Python 3.X as map returns an object instead of a list.

Use range + sum
l = '13456'
sum([int(l[i])*int(l[i+1]) for i in range(len(l)-1)])
#Output:
#65
with range(len(l)-1), you can get the start, end indexes like below
Output:[0, 1, 2, 3]
Looping through the above list and indexing on list l,
int(l[i])*int(l[i+1]) # gives [1*3, 3*4 , ...]
Summing the output list
sum([1*3, 3*4 , ...]) # gives 65

def func(input):
return sum([int(input[i])*int(input[i+1]) for i in range(len(input)-1)])

Related

Taking a 8 bit number and split them into two 4 bit numbers

I have an integer integer = 10101001. I wanted to split that number into an array of 2 four bit numbers array = [1010,1001]. How do I do this? Are there any python methods?
This is a way to do it:
num = 10101001
str_num = str(num)
split_num = [int(str_num[0:4]), int(str_num[4:])]
print(split_num)
Output:
[1010, 1001]
You need to pass by the string version of you int
i = 10101001
str_i = str(i)
res = str_i[:len(str_i) // 2], str_i[len(str_i) // 2:]
print(res) # ('1010', '1001')
If that is indeed the general case, you can use a simple method.
def func(x):
x = str(x) # this takes x and turns it into a string
sub1 = int(x[:4]) # this takes the first 4 digits and turns it into an integer
sub2 = int(x[4:]) # this takes the last 4 digits and turns it into an integer
return [sub1, sub2]
Note that I used the fact that strins are subscriptable. You can fetch characters in a string just like a list.

Format a large integer with commas without using .format()

I'm trying to format any number by inserting ',' every 3 numbers from the end by not using format()
123456789 becomes 123,456,789
1000000 becomes 1,000,000
What I have so far only seems to go from the start, I've tried different ideas to get it to reverse but they seem to not work as I hoped.
def format_number(number):
s = [x for x in str(number)]
for a in s[::3]:
if s.index(a) is not 0:
s.insert(s.index(a), ',')
return ''.join(s)
print(format_number(1123456789))
>> 112,345,678,9
But obviously what I want is 1,123,456,789
I tried reversing the range [:-1:3] but I get 112,345,6789
Clarification: I don't want to use format to structure the number, I'd prefer to understand how to do it myself just for self-study's sake.
Here is a solution for you, without using built-in functions:
def format_number(number):
s = list(str(number))[::-1]
o = ''
for a in range(len(s)):
if a and a % 3 == 0:
o += ','
o += s[a]
return o[::-1]
print(format_number(1123456789))
And here is the same solution using built-in functions:
def format_number(number):
return '{:,}'.format(number)
print(format_number(1123456789))
I hope this helps. :D
One way to do it without built-in functions at all...
def format_number(number):
i = 0
r = ""
while True:
r = "0123456789"[number % 10] + r
number //= 10
if number == 0:
return r
i += 1
if i % 3 == 0:
r = "," + r
Here's a version that's almost free of built-in functions or methods (it does still have to use str)
def format_number(number):
i = 0
r = ""
for character in str(number)[::-1]:
if i > 0 and i % 3 == 0:
r = "," + r
r = character + r
i += 1
return r
Another way to do it without format but with other built-ins is to reverse the number, split it into chunks of 3, join them with a comma, and reverse it again.
def format_number(number):
backward = str(number)[::-1]
r = ",".join(backward[i:i+3] for i in range(0, len(backward), 3))
return r[::-1]
Your current approach has following drawbacks
checking for equality/inequality in most cases (especially for int) should be made using ==/!= operators, not is/is not ones,
using list.index returns first occurence from the left end (so s.index('1') will be always 0 in your example), we can iterate over range if indices instead (using range built-in).
we can have something like
def format_number(number):
s = [x for x in str(number)]
for index in range(len(s) - 3, 0, -3):
s.insert(index, ',')
return ''.join(s)
Test
>>> format_number(1123456789)
'1,123,456,789'
>>> format_number(6789)
'6,789'
>>> format_number(135)
'135'
If range, list.insert and str.join are not allowed
We can replace
range with while loop,
list.insert using slicing and concatenation,
str.join with concatenation,
like
def format_number(number):
s = [x for x in str(number)]
index = len(s) - 3
while index > 0:
s = s[:index] + [','] + s[index:]
index -= 3
result = ''
for character in s:
result += character
return result
Using str.format
Finally, following docs
The ',' option signals the use of a comma for a thousands separator. For a locale aware separator, use the 'n' integer presentation type instead.
your function can be simplified to
def format_number(number):
return '{:,}'.format(number)
and it will even work for floats.

Dividing by the power of digit position of integer

Here is what I want to accomplish :
a = 1235
My result r should calculate 1/2 + 2/(2*2) + 3/(2*2*2) + 5/(2*2*2*2), so
r will output 1.6875
I tried..
s = 123
l = list(map(int, str(s))) # converted into list
print(l)
y = [int(x)/(2**s.index(x)) for x in l]
print(y)
but it does not work.
Don't use index (slow and will return the first index over and over, which is wrong), just iterate on the index (plus 1) of the string using enumerate.
Then feed directly to sum.
BTW your code can be simplified to write this directly in one line:
y = sum(int(x)/(2**i) for i,x in enumerate(str(1235),1))
result:
1.6875

Python loop returning wrong value when multiplying digits in a string

This function is supposed to take a string of numbers(snum) and then the index it is supposed to start at (indx) and then starting at that (indx) and multiply the next (dig) amount of numbers and return the value. This is current funciton should return 72 but it is returning 41472. Thank you!
def product(dig, indx, snum):
length = int(len(snum))
int(indx)
int(dig)
total = int(snum[indx])
for k in range((indx + 1), length):
for i in range(0, dig):
total = total * int(snum[k])
else:
return total
x = product(3, 5, '72890346')
print(x)
Following should do it :
def product(dig, indx, snum):
mul = 1
for s in snum[indx : indx+dig+1]: #Note the `dig+1`
mul *= int(s) #multiply the number
return mul
Driver code :
x = product(3, 5, '72890346')
print(x)
#72
In your code, the logic has few problems. You do not need two loops. Here, we are using slicing operation to get characters between indx and indx+dig, and then converting the string we got to int and multiplying.

Repeating characters results in wrong repetition counts

My function looks like this:
def accum(s):
a = []
for i in s:
b = s.index(i)
a.append(i * (b+1))
x = "-".join(a)
return x.title()
with the expected input of:
'abcd'
the output should be and is:
'A-Bb-Ccc-Dddd'
but if the input has a recurring character:
'abccba'
it returns:
'A-Bb-Ccc-Ccc-Bb-A'
instead of:
'A-Bb-Ccc-Cccc-Bbbbb-Aaaaaa'
how can I fix this?
Don't use str.index(), it'll return the first match. Since c and b and a appear early in the string you get 2, 1 and 0 back regardless of the position of the current letter.
Use the enumerate() function to give you position counter instead:
for i, letter in enumerate(s, 1):
a.append(i * letter)
The second argument is the starting value; setting this to 1 means you can avoid having to + 1 later on. See What does enumerate mean? if you need more details on what enumerate() does.
You can use a list comprehension here rather than use list.append() calls:
def accum(s):
a = [i * letter for i, letter in enumerate(s, 1)]
x = "-".join(a)
return x.title()
which could, at a pinch, be turned into a one-liner:
def accum(s):
a = '-'.join([i * c for i, c in enumerate(s, 1)]).title()
This is because s.index(a) returns the first index of the character. You can use enumerate to pair elements to their indices:
Here is a Pythonic solution:
def accum(s):
return "-".join(c*(i+1) for i, c in enumerate(s)).title()
simple:
def accum(s):
a = []
for i in range(len(s)):
a.append(s[i]*(i+1))
x = "-".join(a)
return x.title()

Categories

Resources