谢乾坤 | Kingname

给时光以生命。

不是因为我高产似那啥。而是因为这些文章是我每天一篇发布在微信公众号上的,然后每隔一段时间整体搬运到博客上面来。

所以还没有关注我微信公众号的同学,请扫描下面的二维码,关注我的公众号,每天一篇原创文章,每天都有新技能 Get。

在上一篇文章里面,我们讲到了如何使用Python的yield关键字简化代码,压平多层嵌套字典的。

那么如果我们的数据不仅仅有字典,还有列表,是一个字典列表多层嵌套的数据怎么办呢?例如:

1
2
3
4
5
6
7
8
9
10
11
12
nest_dict = {
'a': 1,
'b': {
'c': 2,
'd': 3,
'e': {'f': 4}
},
'g': {'h': 5},
'i': 6,
'j': {'k': {'l': {'m': 8}}},
'n': [1, {'o': 1, 'p': [1, 2, 3], 'q': {'r': {'s': 100}}}, 3, [1, 2, 3], 5]
}

现在,请停下来,敲一敲代码,想想如何把处理列表的逻辑添加进去。

首先,我们来看一下最终被压平以后的数据长什么样:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
{'a': 1,
'b_c': 2,
'b_d': 3,
'b_e_f': 4,
'g_h': 5,
'i': 6,
'j_k_l_m': 8,
'n_0': 1,
'n_1_o': 1,
'n_1_p_0': 1,
'n_1_p_1': 2,
'n_1_p_2': 3,
'n_1_q_r_s': 100,
'n_2': 3,
'n_3_0': 1,
'n_3_1': 2,
'n_3_2': 3,
'n_4': 5}

对于'n': ['a', 'b', 'c']这种形式的数据,我们把它转换为: {'n_0': 'a', 'n_1': 'b', 'n_2': 'c'}

阅读全文 »

我们经常遇到各种字典套字典的数据,例如:

1
2
3
4
5
6
7
8
9
10
11
nest_dict = {
'a': 1,
'b': {
'c': 2,
'd': 3,
'e': {'f': 4}
},
'g': {'h': 5},
'i': 6,
'j': {'k': {'l': {'m': 8}}}
}

有没有什么简单的办法,把它压扁,变成:

1
2
3
4
5
6
7
8
9
{
'a': 1,
'b_c': 2,
'b_d': 3,
'b_e_f': 4,
'g_h': 5,
'i': 6,
'j_k_l_m': 8
}
阅读全文 »

写过一段时间代码的同学,应该对这一句话深有体会:程序的时间利用率和空间利用率往往是矛盾的,可以用时间换空间,可以用空间换时间,但很难同时提高一个程序的时间利用率和空间利用率。

但如果你尝试使用生成器来重构你的代码,也许你会发现,在一定程度上,你可以既提高时间利用率,又提高空间利用率。

阅读全文 »

说到安装 Python 的第三方库,会 Python 的同学都知道,在终端使用pip install xxx即可。

那么如果我想在代码里面安装第三方库怎么办呢?可能有人想到使用 os 模块:

1
2
3
import os
package_name = 'requests'
os.system(f'pip install {package_name}')

这种方法确实可行,并且即使你在虚拟环境中使用这种方式安装,也确实不会安装到系统的 Python 环境中。

阅读全文 »

我们在开发的过程中,会创建非常多的日志,对日志进行 rotate 是一个基本要求。

所谓的rotate,可以理解为对日志按照一定的规则进行切分。例如,每天晚上0点生成一个新的日志文件,并把老的文件归档。又或者每个日志文件超过多少 MB 以后就自动切分,并把老的内容单独存档或者压缩。存档以后的日志文件保存多少个。超过数量以后先删除老日志再删除新日志。

如果我们使用的是 Python,那么我们可以使用自带的logging模块或者第三方的logoru来写日志。但如果我们使用像是 MongoDB这种第三方的软件,那么要对日志进行 rotate 就非常麻烦了。如果不加以管理,MongoDB 的日志很容易就达到几十GB。

还有其他软件,他们的日志散落在系统的各个位置,我们应该如何替他们 rotate 呢?

阅读全文 »

假设有一个 Redis 集合,里面有 N 条数据,你不停从里面lpop数据,直到某一条数据的值为'Stop'字符串为止(已知里面必有一条数据为'Stop'字符串,但其位置不知道)。

阅读全文 »

我们平时导入第三方模块的时候,一般使用的是import关键字,例如:

1
2
import scrapy
from scrapy.spider import Spider

但是如果各位同学看过 Scrapy 的settings.py文件,就会发现里面会通过字符串的方式来指定pipeline 和 middleware,例如:

1
2
3
4
5
6
7
8
DOWNLOADER_MIDDLEWARES = {
'Test.middlewares.ExceptionRetryMiddleware': 545,
'Test.middlewares.BOProxyMiddlewareV2': 543,
}

SPIDER_MIDDLEWARES = {
'Test.middlewares.LoggingRequestMiddleware': 543,
}

我们知道,这里的Test.middlewares.ExceptionRetryMiddleware实际上对应了根目录下面的Test文件夹里面的middlewares.py文件中的ExceptionRetryMiddleware类。那么 Scrapy 是如何根据这个字符串,导入这个类的呢?

阅读全文 »

请大家猜一猜下面这段代码的运行效果:

1
2
3
4
5
6
7
8
import random
import time

people = ['kingname', '王小一', '李小二', '张小三', '刘小四', '卢小五', '马小六', '周小七', '丁小八', '朱小九']
for i in range(1, 11):
lucky_guy = random.choice(people)
print(f'第{i}次抽奖,中奖用户:{lucky_guy}')
time.sleep(1)

你是不是以为这段代码运行以后,结果如下图所示?

但实际上,我可以让输出结果根据我的意愿随意变动,例如像下面这个 gif ,所有输出结果都是我:

你可以先不要往下看,放下手机,自己写一下代码,试一试 如何才能实现 gif 中的效果。

阅读全文 »

在我们使用 Python 查询 MongoDB 的时候,一般会使用MongoDB 的集合(collection)对象的 find()方法或者find_one()方法:

1
2
3
4
5
6
7
8
9
10
11
12
13
import pymongo

handler = pymongo.MongoClient().chapter_7.example_data_4

# 获得一个游标操作对象,并迭代
rows = handler.find()
for row in rows:
print(row)


# 查询第一条数据
row = handler.find_one()
print(row)

其中,find()方法返回的是一个游标对象,我们可以直接对这个对象进行迭代,从而按顺序获取每一条数据。

阅读全文 »
0%