Python 包含任何类型项的列表的总和
我正在学习python,我们的老师告诉我们写一个函数,它将返回列表的和,不管它的值是什么类型的 如果列表是整数,则:Python 包含任何类型项的列表的总和,python,list,Python,List,我正在学习python,我们的老师告诉我们写一个函数,它将返回列表的和,不管它的值是什么类型的 如果列表是整数,则:sum([1,4,5,6])=16 如果列表是字符串,那么:sum(['a','b',c'])='abc' 列表也可以由元组和其中的列表组成 代码需要尽可能简短。我试着写下: element = list[0] for thing in list: for thingy in thing: element += thingy print element 但
sum([1,4,5,6])=16
如果列表是字符串,那么:sum(['a','b',c'])='abc'
列表也可以由元组和其中的列表组成
代码需要尽可能简短。我试着写下:
element = list[0]
for thing in list:
for thingy in thing:
element += thingy
print element
但是它不起作用。。你知道怎么做吗?你可以使用
reduce
,而不是内置的sum
,它需要在整个列表或元组中使用整数或浮点数:
s1 = [1, 4, 5, 6]
s2 = ['a', 'b', 'c']
print(reduce(lambda x, y:x+y, s1))
print(reduce(lambda x, y:x+y, s2))
from functools import reduce
print(reduce(lambda x, y:x+y, s1))
输出:
16
abc
abcdeh18ddb
在Python3中,functools
必须使用reduce
:
s1 = [1, 4, 5, 6]
s2 = ['a', 'b', 'c']
print(reduce(lambda x, y:x+y, s1))
print(reduce(lambda x, y:x+y, s2))
from functools import reduce
print(reduce(lambda x, y:x+y, s1))
编辑:要对嵌套列表的值求和,最好使用递归,因为列表可以具有任意深度:
def flatten(l):
return reduce(lambda x, y:x+y, [i if not isinstance(i, list) else flatten(i) for i in l])
print(flatten([['a', 'b', 'c'], ['d', 'e', ['h', ['18', 'dd', 'b']]]]))
输出:
16
abc
abcdeh18ddb
您的代码无法工作,因为您将第一个元素连接/求和两次 示例:-
让我们假设
listy=[1,2,3,4,5]
&
element=listy[0]=1
现在开始第一次迭代
element=element+thingy(1+1)
,因为第一次迭代的thingy也指向listy[0]
只需检查列表中元素的类型:-
例如
if isinstance(string, list[0]) :
sum = ""
elif isinstance(int, list[0]):
sum = 0
else :
// raise some error
for i in listy:
sum += i
首先,我应该指出您将
元素初始化为列表[0]
的错误。。。您将添加两次
所以,要解决这个问题,我的第一反应是从-
def generic_sum(data):
return sum(data, type(data[0])())
但这仅适用于整数和浮点数、列表和元组以及计数器
对象(字符串也有\uuuuuuuuuuu添加
方法,但它们是求和
特殊情况)
因此,我们需要一个更通用的解决方案,它应该适用于任何类型的数据
这里有一个,但是您需要注意列表元素可以任意嵌套。我的方法是首先将数据展平,然后对其元素求和
幼稚的做法是——
flat_data = [y for x in data for y in (x if isinstance(x, list) else [x])]
您也可以这样写:
flat_data = []
for x in data:
if not isinstance(x, list):
x = [x]
flat_data.extend(x)
然后呢,
init = flat_data[0]
for v in flat_data[1:]:
init += v
将其放入函数中,您有-
def generic_sum(data):
flat_data = [y for x in data for y in (x if isinstance(x, list) else [x])]
sum_ = flat_data[0] # don't use `sum`, you hide the builtin that way
for v in flat_data[1:]:
sum_ += v
return sum_
下面是一些示例输入的演示-
如果你想提高效率,我建议你做两件事-
对数值使用sum
,而不是使用循环手动相加,然后
特殊套管柱,通过对其调用str.join
,而不是求和
它的工作原理与上面相同,但是对于字符串连接应该更有效
注意
- 对于python2,使用
isinstance(flat_data[0],basestring)
(因为可以使用str
或unicode
对象)
- 调用
str.join
在计算上比求每个字符的和(二次时间)便宜(线性时间)。这是字符串不可变这一事实的结果
基准
data = ['a', 'b', ['c', 'd']] * 1000000
在处理数百万个元素时,这两种方法都会跨越一秒钟。我认为这是因为变平的步骤。或者,让我们在平面数据上计算求和代码的时间
flat_data = ['a', 'b', 'c', 'd'] * 1000000
这更有意义,并且更好地表明在循环中串联字符串的效率低下
此外,generic\u sum\u opt
对数字求和更快
data = [[1], 2, 3, [4, 5, 6]] * 1000000
由于在那里使用了sum
,第二个函数肯定更快 为什么不起作用?对于数字,错误是:“int”对象不可iterable,对于字符串,字符串的第一个元素有两次。对于元组和列表,我得到了更多的错误,只需对列表中的东西执行::element+=thing
。为什么是第二个循环?@cᴏʟᴅsᴘᴇᴇᴅ 因为列表中可能有一个列表。我还需要对内部列表中的所有值求和,不要将list
用作变量名<代码>列表()
是一个,您可以用脚本覆盖它。告诉你的老师,他/她应该教你蟒蛇。谢谢,我不知道这个功能。对于内部列表和元组会这样吗?@eitanmayer假设嵌套列表是['a','b','c'],['d','e','f']
。您希望从该列表中得到什么<代码>['abc','def']或'abcdef'
?abcdef-函数应包含所有内容one@coldspeed为什么(四元时间)@MukulSharma每次你向另一个字符串添加一个字符串时,你必须分配新的内存,这是线性的,而且是浪费的。执行线性运算的次数是线性的,因此它是二次的。@MukulSharma字符串串联每次都需要创建一个全新的字符串。@coldspeed and how join avoidthat@MukulSharma自从您提出要求以来,我们已经为该功能投入了大量的工作,以优化其效率。问题的关键在于,内存只分配一次,而且是线性的(尽管细节有点不确定)。本问答提供了一个良好的视角:
%timeit generic_sum_opt(data)
1 loop, best of 3: 1.21 s per loop
flat_data = ['a', 'b', 'c', 'd'] * 1000000
%%timeit
sum_ = flat_data[0] # don't use `sum`, you hide the builtin that way
for v in flat_data[1:]:
sum_ += v
1 loop, best of 3: 623 ms per loop
%timeit ''.join(flat_data)
10 loops, best of 3: 35.5 ms per loop
data = [[1], 2, 3, [4, 5, 6]] * 1000000
%timeit generic_sum(data)
1 loop, best of 3: 1.94 s per loop
%timeit generic_sum_opt(data)
1 loop, best of 3: 1.53 s per loop