gpt4 book ai didi

python - 包含任何类型项目的列表总和

转载 作者:行者123 更新时间:2023-11-28 21:38:29 25 4
gpt4 key购买 nike

我正在学习 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

但它不起作用..知道如何做到这一点吗?

最佳答案

首先,我应该指出你将 element 初始化为 list[0] 的错误...你将添加它两次 .

所以,要解决这个问题,我的第一直觉是从 -

def generic_sum(data):
return sum(data, type(data[0])())

但这只适用于整数和 float 、列表和元组以及 Counter 对象(字符串也有一个 __add__ 方法但是 sum 特殊案例他们)。

因此,我们需要一个适用于任何类型数据的更通用的解决方案。


这是一个,但您需要注意列表元素可以任意嵌套这一事实。我的方法是首先展平您的数据,然后对其元素求和。

一个天真的方法是 -

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_

这是一些示例输入的演示 -

>>> generic_sum([[1], 2, 3, [4, 5, 6]])
21

>>> generic_sum(['a', 'b', ['c', 'd']])
'abcd'

如果您正在寻找效率,我会在这里推荐两件事 -

  1. 对数值使用sum,而不是通过循环手动将它们相加,并且
  2. 特殊大小写 字符串,通过对它们调用 str.join,而不是将它们相加。

def generic_sum_opt(data):
flat_data = [y for x in data for y in (x if isinstance(x, list) else [x])]
return sum(flat_data) if not isinstance(flat_data[0], str) else ''.join(flat_data)

它的工作原理与上面相同,但对于字符串连接应该更有效。

>>> generic_sum_opt([[1], 2, 3, [4, 5, 6]])
21

>>> generic_sum_opt(['a', 'b', ['c', 'd']])
'abcd'

注意

  • 对于 python2,请改用 isinstance(flat_data[0], basestring)(因为您可以拥有 strunicode 对象).

  • 调用 str.join 在计算上比对每个字符求和(二次时间)更便宜(线性时间)。这是字符串不可变这一事实的结果。


基准

data = ['a', 'b', ['c', 'd']] * 1000000

%timeit generic_sum(data)
1 loop, best of 3: 1.83 s per loop

%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

这更有意义,并且更好地表明了在循环中连接字符串的总体效率低下。

此外,generic_sum_opt 对数字求和速度更快。

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

由于使用了 sum,第二个函数肯定更快。

关于python - 包含任何类型项目的列表总和,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48192785/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com