Reputation: 3
I'm working on a simple python script that takes a number, converts it to binary, and returns the sum of the binary digits. Here is what I have so far.
#!/usr/bin/python
def sum2(n):
a = str(bin(n))
b = a.replace('0b', '')
return sum([map(int, x) for x in b])
n = int(raw_input("Input number>"))
print sum2(n)
In plain English I take n and convert it to binary, and then convert it to a string. I chop off the 0b (from bin()) and convert the binary characters into a list of ints and then attempt to sum() them.
When trying to figure out how to add the digits together I googled around and found that I should be able to sum() a list of ints. When I attempt to do this, I end up with this traceback.
Traceback (most recent call last):
File "D:\scripts\sum2n1.py", line 9, in <module>
print sum2(x)
File "D:\scripts\sum2n1.py", line 6, in sum2
return sum([map(int, x) for x in b])
TypeError: unsupported operand type(s) for +: 'int' and 'list'
So I find out sum() needs an "iterable" to do it's job. I google around and find there's an iter() function I can call, but it doesn't seem to work.
There's also __iter__() which doesn't work either.
Can anyone tell me what I'm doing wrong? I'm still quite a bit of a beginner. Thanks in advance.
(And no, it's not my homework.)
Upvotes: 0
Views: 6187
Reputation: 143022
This works:
def sum2(n):
idx = 3 if n < 0 else 2 # adjust index for slice based on neg/pos number
a = bin(n)[idx:] # doesn't assign the '0b' (or '-0b' for negatives)
return sum(int(i) for i in a) # convert chars into ints and sum
Note, using slice notation to eliminate the leading '0b'
or '-0b'
is preferable to using replace()
.
You can use list comprehension, or a generator expression for this.
Update:
In a helpful comment @DSM pointed out that negative numbers have '-0b'
in front of the binary string, I updated the code to deal with this by adjusting the slice based on the sign of the number.
Upvotes: 3
Reputation: 1881
One using reduce :
ans = reduce(lambda x,y:int(x)+int(y), L)
Upvotes: 0
Reputation: 304205
Why not simply
def sum2(n):
return sum(x=='1' for x in bin(n))
or even more simply
def sum2(n):
return bin(n).count('1')
Upvotes: 6
Reputation: 87084
Don't wrap the map call in the list comprehension.
Instead of
return sum([map(int, x) for x in b])
Do this:
return sum(map(int, b))
Upvotes: 1
Reputation: 86718
You are combining list comprehensions with the map
function, in an apparent attempt to do the same thing twice. You want either:
sum(int(x) for x in b)
or
sum(map(int, b))
Upvotes: 5
Reputation: 251398
By doing [map(int, x) for x in b]
, you are doing the same thing twice. map(int, b)
would make each digit an int. Or [int(x) for x in b]
would do the same. But you are doing both. Pick one or the other. Try:
sum([int(x) for x in b])
Upvotes: 2
Reputation: 113988
try doing this instead on your return
return sum(map(int,b))
that should work
Upvotes: 2