0

我正在编写一个简单的 python 脚本,它接受一个数字,将其转换为二进制,并返回二进制数字的总和。这是我到目前为止所拥有的。

#!/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)

在简单的英语中,我将n转换为二进制,然后将其转换为字符串。我砍掉0b(来自bin())并将二进制字符转换为整数列表,然后尝试sum()它们。

当试图弄清楚如何将数字相加时,我搜索了一下,发现我应该能够sum()一个整数列表。当我尝试这样做时,我最终得到了这个回溯。

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'

所以我发现sum()需要一个“可迭代”来完成它的工作。我四处搜索,发现有一个可以调用的 iter() 函数,但它似乎不起作用。

There's also __iter__() which doesn't work either.

谁能告诉我我做错了什么?我还是个初学者。提前致谢。

(不,这不是我的作业。)

4

7 回答 7

6

为什么不简单

def sum2(n):
    return sum(x=='1' for x in bin(n))

甚至更简单

def sum2(n):
    return bin(n).count('1')
于 2012-07-18T04:41:47.593 回答
5

您正在将列表推导与map函数结合起来,显然是在尝试两次做同样的事情。你想要:

sum(int(x) for x in b)

或者

sum(map(int, b))
于 2012-07-18T04:28:00.963 回答
3

这有效:

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

请注意,使用切片表示法消除前导'0b''-0b'优于使用replace().

您可以为此使用列表推导或生成器表达式。

更新

在一个有用的评论中@DSM 指出'-0b'二进制字符串前面有负数,我更新了代码来处理这个问题,方法是根据数字的符号调整切片。

于 2012-07-18T04:27:02.670 回答
2

尝试在您返回时执行此操作

return sum(map(int,b))

那应该工作

于 2012-07-18T04:26:56.037 回答
2

通过做[map(int, x) for x in b],你做同样的事情两次。 map(int, b)将使每个数字成为一个整数。或者[int(x) for x in b]也会这样做。但你两者都做。选择一个或另一个。尝试:

sum([int(x) for x in b])
于 2012-07-18T04:27:03.953 回答
1

不要将 map 调用包含在列表理解中。

代替

return sum([map(int, x) for x in b])

做这个:

return sum(map(int, b))
于 2012-07-18T04:29:39.833 回答
0

一种使用 reduce :

ans = reduce(lambda x,y:int(x)+int(y), L)
于 2012-07-18T04:43:56.027 回答