若是有更好的技巧或者是一些心得也能夠分享給我~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