若是有更好的技巧或者是一些心得也能够分享给我~python
test = [1, 2, 3, 4, 5]
# 从索引最开始到结束,每隔两个取出一个
# 实际上就是肉眼数的奇数位,索引的偶数位
odds = test[::2]
print(odds) # 结果 -> [1, 3, 5]
# 从索引第一位到结束,每隔两个取出一个
# 实际上就是肉眼数的偶数位,索引的奇数位
evens = test[1::2]
print(evens) # 结果 -> [2, 4]
# 对于byte的字符串来讲还有神奇的特效(only byte)
byte_str = b'abcd'
print(byte_str[::-1]) # 结果 -> dcba
# 尽可能不要很复杂的切片方式,尽可能可以屡次解决复杂
# 不要同时出现start end stride三个参数复制代码
# 1. 例子没有
# list, dict, set都有对列表表达式的支持
# 列表表达式代替使用map和filter,能够避免写lambda函数
# 2. 例子
# 列表表达式处理多重for循环
martix = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
flat_list = [x for row in martix for x in row]
print(flat_list) # 结果 -> [1, 2, 3, 4, 5, 6, 7, 8, 9]
# 拆解代码大体就是:
new_list = []
for row in martix:
for x in row:
new_list.append(x)
# 3.例子
# 从一个列表中找出一个数字大于4且是偶数的
a = [1, 2, 3, 4, 5, 6, 7, 8, 9]
# 第一种
b = [x for x in a if x > 4 if x % 2 ==0]
# 第二种
c = [x for x in a if x > 4 and x % 2 ==0]
# 结果都是同样的,只是判断上的区别
# Tips:
# 列表表达式能用就尽可能用,能够缩减一些代码量,可是不要写的过于复杂
# 太复杂的表达式,查bug更难找,并且也不利于别人进行维护复制代码
# 缘由很简单,列表表达式须要开辟较大的内存空间进行存储
""" 官方解释: 生成器表达式,它是对推导和生成器的一种泛化。 生成器在运行时不会将整个输出序列呈现出来,而是会估值为迭代器, 这个迭代器每次能够根据生成器表达式产生一项数据。 """
# 1. 例子
# 读取一个多行文本,统计每一行的长度
it = (len(x) for x in open('<文件路径>/<文件名>.<文件后缀>')
print(it) # 结果 -> <generator object <genexpr> at 某个内存地址>
# 须要输出时就用next
print(next(it))复制代码
# 缘由很简单,封装的比range好
test = ['vannila', 'chocolate', 'pecan', 'strawberry']
# 第一种
for i , flavor in enumerate(test):
print('%d: %s' % (i + 1, flavor))
# 结果以下
>>>
1: vannila
2: chcolate
3: pecan
4: strawberry
# 解释一下: i + 1 实际上就是为了更好看,若是不i + 1,实际上就是索引的位置.
# 第二种
for i , flavor in enumerate(test, 1):
print('%d: %s' % (i, flavor))
# 结果同样, 实际上就是在enumerate的函数中已经封装了
# 显得更简便,并且同时能输出索引位置或输出实际中的计数位复制代码
# except的例子就不说了,用过都知道
# 直接上else的例子
# 函数的功能就是: 加载一个json,返回对应key的值
def load_json_key(data, key)
try:
result_dict = json.loads(data)
except ValueError as err:
raise KeyError from err
else:
return result_dict[key]
"""
解释:
实际上这个else可要可不要,由于写在try里面也是能够的
可是若是为了代码的可阅读性,else是一个很必要的东西
代码阅读上就知道try里面是代码中可能存在错误的的地方
若是写在一堆的话,还有错误,那你的except就要增长多几个了
并且写代码也并不建议嵌套try-except,毕竟那不服合代码的风格.
"""
# finally的话,实际上就一个代码清理的过程
# 通常用在IO或者数据库读写上,用来关闭流, 例子就不写了.复制代码
# coding: utf-8
from concurrent.futures import ThreadPoolExecutor as Pool
# from multiprocessing import Pool
import requests
import time
urls = ["http://www.gzcc.cn", "http://jwxw.gzcc.cn",
"http://www.baidu.com", "http://www.qq.com",
"http://www.163.com", "http://www.sohu.com"]
def task(url, timeout=10):
return requests.get(url=url, timeout=timeout)
if __name__ == '__main__':
start_1 = time.time()
for each_url in urls:
response = task(url=each_url)
print('%s, %s' % (response.url, response.status_code))
end_1 = time.time()
print("顺序执行的时长: %f" % (end_1 - start_1))
start_2 = time.time()
pool = Pool(max_workers=4)
# pool = Pool(processes=4)
processes = pool.map(task, urls)
for each_process in processes:
print('%s, %s' % (each_process.url, each_process.status_code))
end_2 = time.time()
print("并行执行的时长: %f" % (end_2 - start_2))
# 第一种的结果: 1.4s
# 第二种的结果: 0.4s
# 结果的提高是确定有的,可是和网络状况有关系。
# 关于导入的包 concurrent.future
# 对于这个包里面的ThreadPoolExecutor和multiprocessing的Pool对比,做用实际上差很少,具体时间差别我还没怎么测试过.
# 可是若是你认真看源码的话会发现,实际上future的包在process的那一块也是调用multiprocessing的
# 按照源码的意思就是在子线程中运行多个python的解释器,从而实现并行.
# 可是通常的代码或者多线程爬虫上基本体会不出,由于爬虫的核心仍是在网络速度上,而通常的代码也不必
# 除非计算矩阵或者其余的须要巨大计算量的时候再考虑使用.复制代码
# 例子
rate = 1.45
seconds = 3 * 60 + 42
cost = rate * seconds / 60
print(cost) # 结果很奇怪: 5.364999999999999
# 这时候可能会想到用round的函数
# 一、若是这时你的需求是不足一分也当一分的计算
# 相似于向上取整round的方法会把结果变成5.36而不是5.37
# 二、若是没有要求的时候使用round就能够了
#
# 针对第一种问题,就引出一个decimal的方法了,改写一下
from decimal import Decimal
rate = Decimal('1.45')
seconds = Decimal(3 * 60 + 42)
cost = rate * seconds / Decimal(60)
print(cost) # 结果 -> 5.365
# 重点说下这里。
# 有个很奇怪的地方,有兴趣的能够研究下为何。
# 把rate的那个1.45去掉单引号包围,再运行就明白为何奇怪了
# 反观结果, 5.365貌似也不是咱们想要的,这里就引入一个quantize方法了
# 在代码顶部加上
from decimal import ROUND_UP
# cost仍是刚刚的cost
rounded = cost.quantize(Decimal('0.01'), rounding=ROUND_UP)
print(rounded) # 结果 -> 5.37
# 兜兜转转就到结果这里了.通常这些状况都是对精度要求很高才须要,通常状况就当看不见好了.复制代码
你的代码在导包的时候写了import *,你本身开发是很明白有什么方法的.
可是在协做开发或者开源项目的时候尽可能避免.
由于其余开发者并不知道里面的方法是干啥的.复制代码
# 例如一些数据库的配置,selenium的webdriver的配置,甚至开发的模式配置能够经过一些json格式的配置文件进行维护.
# 好处1: 在于这样管理项目不用"东奔西跑",为了一个全局变量找半天
# 好处2: 在协同开发的时候,能够不用变更的代码的状况下,根据本身的开发环境肯定一些全局配置
# 缺点的话,实际上也算不上缺点.就是每次都要读取一次配置文件,代码的速度会减慢一点点,可是并不碍事.复制代码
回到顶部: 传送门web