Python notes [two]

Before sharing once I learn the notes Python, Python notes [A] , recently some new harvest, to share;

random.sample () does not overlap a random number

Work, sometimes need to manually create a database to some data, some fields similar order_id, are generally not repeated (without considering other unusual circumstances refunds under), to build ultra-quantity, not duplicate order_id, how to do?

Recommended random.sample ();

In the face of actual generate random integers, my first reaction was random.randint (), we compared:
Here Insert Picture Description
circulation random.randint (), actually will be repeated, but random.sample () will not be repeated, the specific reasons: source in comments
Here Insert Picture Description

String find ()! = -1

Here Insert Picture Description
find () comprises detecting whether the substring string sub, if the specified start and end range, it is checked whether contained within the specified range, if the substring returns the index contains substring, otherwise -1.

Here mainly want to say: Return -1 on failure
because I often can not determine the index of the substring, but use str_xx.find ( 'xxxx) = -1 will be more!.

Beginning of the string, the end of the startswith () \ endwith ()

Sometimes in order to determine whether a string is a substring beginning, the end, it is necessary to use startswith (), endswith ();
Here Insert Picture Description
Here Insert Picture Description
here say is above that line in Figure 2 where the mouse prefix can also be a tuple of strings to try. a suffix parameter passing all of the tuple str, it can be used to determine the N elements.

Here Insert Picture Description

list.index () == -1 [WRONG]

标题是错误的(我在遇到第2次,才反应过来);
一直以来,访问列表的最后一个元素,我用的是list[-1],不知不觉就和list.index()用乱了。

list.index(obj):从列表中找出某个值第一个匹配项的索引位置
我之所以用list.index(obj) == -1, 是想当然认为 list的最后一个元素的索引是-1; 但实际索引是从0开始【大于等于0】;

    def test_20200221b(self):
        list_data = ['1', '2', '65', 'zy', 'zyooooxie', 'csdn']
        check_ele = 'xie1111'
        for d in list_data:
            print(list_data.index(d))
            if d.find(check_ele) != -1:
                print('找到')
                break

            else:
                if list_data.index(d) == -1:
                # if d == list_data[-1]:
                    print('最后一个 没找到')

拿这个用例来做个说明,想看下list_data下面哪个元素可以find(check_ele),如果找到就结束for循环;如果最后那个元素也不符合,就 print没找到;

实际执行结果:
Here Insert Picture Description
为什么没有 print‘没找到’? 实际就是 else里面 if判断出了问题【列表的索引 不会等于 -1】;
Here Insert Picture Description

字符串 replace()

先看下源码:Here Insert Picture Description

Here Insert Picture Description

我是很喜欢用replace() 的,总结:
1.replace() 返回一个字符串的副本,其中出现的旧字符(old)被替换为新的(new),可选地将替换数count限制为最大值;
2.不传count,会把当前所有符合的old都替换为new ;
3.old的参数不存在,不报错,生成的新字符串和原 string 保持一致 ;
4.可以多次replace() ;
5.replace 不会改变原 string 的内容;
6.count 传超过 实际替换次数,也不会报错;

递归

说起递归,就想起以前面试的时候遇到过2次这样的考题,很有印象的;

这儿说一个情景:我今天发生5笔交易【-10,+20,-15,+124,-156】,最初手上是50块钱,每笔交易之后我手上多少钱?

思路:50-10 为第一笔交易后的钱【期初 + 第一笔】; 50-10+20 为第二笔交易的钱【第一笔交易后的钱 + 第二笔】; 50-10+20-15 为第三笔交易的钱【第二笔交易后的钱 + 第三笔】,依此类推;

    def fun_Recursive(self, x, x_list, opening):
        if x == 0:
            return round(opening + x_list[0], 2)
        else:
            return round(self.fun_Recursive(x-1, x_list, opening) + x_list[x], 2)

Here Insert Picture Description
这样就可以得到: 每笔交易后 手上的钱数 40, 60, 45, 169, 13。

若干笔交易,是不是也很容易得到结果呢?
实际,递归次数太多,会报错 maximum recursion depth exceeded;
Here Insert Picture Description
针对这问题,咋解决? 手动设置 递归次数限制:
Here Insert Picture Description
代码如下:

import sys
sys.setrecursionlimit(10000)

这儿虽然设置为10000次,但我电脑在3200次左右,内存差不多吃不消;【下图和前面的是同一条用例,只是设置了setrecursionlimit】
Here Insert Picture Description

倘若 交易量真为数千笔呢?数万笔呢?

    def test_20200222_abc(self):
        amount_list = random.sample(range(6000, 600000000000), 359162)
        # 单笔交易Amount在6000-600000000000,共发生359162笔交易;期初设置为500
        opening = 500

        if len(amount_list) <= 3000:       # 将3000作为1次递归的长度
            # dg_last_value = self.fun_Recursive(len(amount_list) - 1, amount_list, opening)
            # print(dg_last_value)
            dg_value = [self.fun_Recursive(d, amount_list, opening) for d in range(len(amount_list))]
            Log.info(dg_value)

        else:
            # ci_shu = math.ceil(len(amount_list) / 3000)
            ci_shu = int(math.ceil(len(amount_list) / 3000))        # 加不加int一样

            last_list = [list() for o in range(ci_shu)]

            for a in range(ci_shu):
                if a == 0:
                    print(a * 3000, (a+1) * 3000)
                    new_list = amount_list[a * 3000:(a+1) * 3000]
                    dg_value_0 = [self.fun_Recursive(i, new_list, opening) for i in range(len(new_list))]
                    last_list[a].extend(dg_value_0)
                else:
                    print(a * 3000, (a+1) * 3000)
                    new_list = amount_list[a * 3000:(a+1) * 3000]
                    dg_value_other = [self.fun_Recursive(i, new_list, last_list[a - 1][-1]) for i in range(len(new_list))]
                    last_list[a].extend(dg_value_other)

            Log.info('每一笔交易后的钱数, 以3000笔为一组, {}'.format(last_list))
            Log.info('直接sum() 计算结果:{}'.format(sum(amount_list) + opening))
            Log.info('多次递归,最后一组 最后一笔交易后的钱数:{}'.format(last_list[-1][-1]))

计算过程:
Here Insert Picture Description
最后的结果:

期初设置为500;单笔交易Amount在6000-600000000000,共发生359162笔交易;

Here Insert Picture Description

sum()

前面递归那一块的代码,最后面我写的是 ‘直接sum() 计算结果:{}’.format(sum(amount_list) + opening),
现在再看下 sum()

result=sum(iterable[, start])
sum() 是返回序列iterable的总和,可选参数start表示从该值开始加起来,默认为0;

换个角度想,sum()来做那个情景是不是更好呢?
【某一笔的交易后的钱数,都是amount_list此元素之前all元素的和 + 期初】

Here Insert Picture Description
如果跑几十万的amount呢?
Here Insert Picture Description

出现了数据量太大【将近36w】,迟迟拿不到结果的情况;(可能是我电脑配置不够的原因)

把每次传的amount_list 改动下:

    def test_20200225a(self):
        amount_list = random.sample(range(6000, 600000000000), 173219)
        # 单笔交易Amount在6000-600000000000,共发生173219笔交易;期初设置为500
        opening = 500
        last_list = list()
        if len(amount_list) >= 10000:
            cishu = int(math.ceil(len(amount_list) / 10000))

            for i in range(cishu):
                if i == 0:
                    print(i * 10000, (i+1) * 10000)
                    new_list = [sum(amount_list[0: a], opening) for a in range(1, 10001)]
                    last_list.extend(new_list)
                else:
                    print(i * 10000, (i + 1) * 10000)
                    new_list = [sum(amount_list[i * 10000: i * 10000 + a], last_list[-1]) for a in range(1, 10001)]
                    last_list.extend(self.delete_repeat(new_list))      # 删除重复元素
        else:

            last_list = [sum(amount_list[:a], opening) for a in range(1, len(amount_list) + 1)]

        # Log.info(last_list)
        # Log.info(len(last_list))
        Log.info('直接sum() 计算结果:{}'.format(sum(amount_list) + opening))
        Log.info('最后一笔交易后的钱数:{}'.format(last_list[-1]))

Here Insert Picture Description

Exchange of technical welcome + QQ \ micro letter 153132336 zy
personal blog https://blog.csdn.net/zyooooxie

Published 78 original articles · won praise 24 · views 30000 +

Guess you like

Origin blog.csdn.net/zyooooxie/article/details/103815286