3

An integer like:

number = 1873

I have a formula: weighted_sum = 1*1 + 8*2 + 7*3 + 3*4 = 50. I want to calculate weighted sum of four digits, so output looks like:

1234 weighted sum: 30 / 4321 weighted sum:20

I tried to convert integer to string, but did't work.

number = str(1742)
weighted = number[0]*1 + number[1]*2 + number[2]*3 + number[3]*4
print(number, "weighted sum:", weighted)

Output

1742 Weight Sum: 1774442222

6 Answers 6

4

You need to convert the individual digits back to integer before multipyling them:

weighted = int(number[0])*1 + int(number[1])*2 + int(number[2])*3 + int(number[3])*4

Just taking number[i] will give you a single-character string with of that digit, and multiplying a string bt n in Python means concatenating it n times.

This can be simplified using sum() and a generator expression:

weighted = sum(i * int(digit) for i, digit in enumerate(number, 1))
Sign up to request clarification or add additional context in comments.

4 Comments

How to do achieve this without using string?
@Kee You need to perform the conversion to the decimal system manually to do this without using a string, i.e. divide by ten in a loop and store the sequence of remainders.
@SvenMarnach. You first weighted does not work properly. Not number[3] and number[4] . These will be number[2] and number[3] respectively.
@Md.RezwanulHaque Yeah, I just copied that from the question and didn't realize the indices were wrong. I only checked the first two. :)
3

So if you want to do it using string you have to do this kind of thing (If i use your logic)

number = str(1742)
weighted = int(number[0])*1 + int(number[1])*2 + int(number[2])*3 + int(number[3])*4
print(number, "weighted sum:", weighted)

In fact in python if you multiply a string by an int it repete it multiple time. For example

>>>"a" * 3
"aaa"
>>>"foo" * 2 
"foofoo"

One smaller way to do it is using a list comprehension

number = 1742
sum([i * int(nb) for i,nb in enumerate(str(number))])

One ugly way to do it without string as asked is

number = 1742
weighted = 0
for i in range(0,4):
    temp = number // 10 ** (4-i)
    weighted += i * temp
    number -= temp * 10 ** (4-i)

I tried to do a time analysis using timeit.timeit and we get

  • My first answer (without loop)

    >>> timeit.timeit(..., number = 1000000) 1.3271157014933124

  • For the answer of Sven Marnach using generator

    >>>timeit.timeit("sum(i * int(digit) for i, digit in enumerate(str(1742),1))", number = 1000000) 2.0325663901261066

  • For my answer using list comprehension

    >>> timeit.timeit("sum([i * int(nb) for i,nb in enumerate(str(1742))])", number = 1000000) 1.918556083665976

  • For my answer without any string

    timeit.timeit("number = 1742 ....) 2.8422619991572446

  • For ikku answer without any string

    >>>timeit.timeit(..., number = 1000000) 1.2137944809691135

So it seems that here the faster that I tested with string and loop is a list comprehension.

the faster that I tested with string is the first answer I gave.

The faster that I tested is Ikku answer

2 Comments

You first weighted does not work properly. Not number[3] and number[4] . These will be number[2] and number[3] respectively.
Yeah sorry you're right i just copied and pasted the question and didn't saw that ;) ! Thank you !
0

A way to do it without using strings:

import math

number = 1873
answer = 0
length = math.ceil(math.log10(number))

while length > 0:
    current_digit = number % 10
    answer += current_digit * length
    number = number // 10
    length -= 1

print(answer)

Here I use log10 and ceil to calculate the number of digits in number. Then we loop through all numbers from right to left. We get the current_digit, calculate the current value and add it to answer. At the end of the loop we update number by removing the last digit (dividing by 10) and decrease the loop variable.

Comments

0

An alternative approach would be this one:

dlist=[]
number=1234

while number:
    digit = number % 10
    dlist += [digit]
    number //= 10

print(sum([a*b for a,b in zip(dlist, range(len(dlist),0,-1))]))

To briefly explain it: You get all digits of the number and store it to a list.

dlist = [4][3][2][1]

Then you take another list Then, within the zip-command we create another list starting from leng-of-your-dlist to 1 (steps -1):

[4][3][2][1]

Then we multiply each element of dlist with the newly generated list.

Finally, the sum command calculates the sum of it

Comments

0

Your code does not work properly because of this line weighted = number[0]*1 + number[1]*2 + number[3]*3 + number[4]*4. So, instead of this line use following line :

weighted = int(number[0])*1 + int(number[1])*2 + int(number[2])*3 + int(number[3])*4

And your full code will be like this :

number = str(1742)
weighted = int(number[0])*1 + int(number[1])*2 + int(number[2])*3 + int(number[3])*4
print(number, "weighted sum:", weighted)

Output :

1742 weighted sum: 35

And

number = str(1742)
weighted = (number[0])*1 + (number[1])*2 + (number[2])*3 + (number[3])*4
print(number, "weighted sum:", weighted)

Output :

1742 weighted sum: 1774442222

Comments

0

your approach would have worked fine, except that a string multiplied by number n is a concatenation of n times that string in python, so "7"*2 becomes the string "77", not the number 14

You want actual integer multiplication and as such have to change this line:

weighted = number[0]*1 + number[1]*2 + number[2]*3 + number[3]*4

to this:

weighted = int(number[0])*1 + int(number[1])*2 + int(number[2])*3 + int(number[3])*4

Whether the conversion to and from string is very efficient is a different question, but it should work.

1 Comment

You weighted does not work properly. Not number[3] and number[4] . These will be number[2] and number[3] respectively. –

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.