这一期是我从之前的 Python 笔记 【一】 单独拿出来的,最初只是写的递归,后面慢慢补充了sum() 、reduce()、循环、尾递归; 因为每隔一段时间对这个需求 有些补充,再写到那一期就略显多余,干脆专门拉出来弄一期了。
个人博客:https://blog.csdn.net/zyooooxie
需求
一个情景:某个商店,今天进货、卖东西,总共发生5笔交易【-10.5,+20.6,-15,+124.8,-156】,最初手上是50块钱,想知道 每笔交易发生后 手上有多少钱?
过程:50-10.5 为第一笔交易后 手上的钱【期初 + 第一笔】; 50-10.5+20.6 为第二笔交易后 手上的钱【第一笔交易后的钱 + 第二笔】; 50-10.5+20.6-15 为第三笔交易后 手上的钱【第二笔交易后的钱 + 第三笔】,依此类推;
若100w笔交易订单 那该咋做呢?
reduce()
对amount_list的每个元素进行 遍历,每个元素都做一次 reduce()求和;
def get_balance_list(self, amount_list, opening_balance):
from functools import reduce
balance_list = list()
for r in amount_list:
r_index = amount_list.index(r)
amount = amount_list[0:r_index + 1]
# Log.info(amount)
balance = reduce(lambda x, y: x+y, amount, opening_balance)
# Log.info(balance)
balance_list.append(balance)
Log.info(balance_list[-1])
优化下,代码真的简洁呀
def get_balance_list_1(self, amount_list, opening_balance):
from functools import reduce
balance_list = [reduce(lambda x, y: x + y, amount_list[0:amount_list.index(a) + 1], opening_balance)for a in amount_list]
Log.info(balance_list)
执行时间和 其他方法的对比:
感觉 获取 balance_list 就有点慢了。 所以前面我的代码 有问题;
换个角度想,reduce() 生成 最后那个元素 ,那意味着 在迭代过程,其他元素也生成了。我想要拿到其他元素【即 每笔交易后的balance】,咋做呢?
先看下 大佬们对reduce() 的概括:
修改下
def reduce_func(func, seq, init_num=None):
if init_num is not None:
ret = init_num
else:
ret = seq.pop(0)
ele = list()
for i in seq:
ret = func(ret, i)
ele.append(ret)
return ret, ele
while 循环
def while_sum(amount_list, opening_balance):
tot = len(amount_list)
i = 0
result = opening_balance
result_list = list()
while i < tot:
abc = amount_list[i]
result += abc
result_list.append(result)
i += 1
print(result_list)
for 循环
def for_sum(amount_list, opening_balance):
balance_list = list()
tot = len(amount_list)
abc = opening_balance
for a in range(tot):
abc += amount_list[a]
balance_list.append(abc)
print(balance_list)
def test_for(amount_list, opening_balance):
balance_list = list()
res = opening_balance
for i in amount_list:
res = i + res
balance_list.append(res)
Log.info(balance_list)
accumulate()
【20230215更新】
https://docs.python.org/zh-cn/3.8/library/itertools.html#itertools.accumulate
"""
@blog: https://blog.csdn.net/zyooooxie
@qq: 153132336
"""
def test_accumulate(amount_list, opening_balance):
from itertools import accumulate
res = accumulate(amount_list, initial=opening_balance)
Log.info(list(res))