listtosetpython
㈠ 如何對列表進行排序 python
很多時候,我們需要對List進行排序,Python提供了兩個方法,對給定的List
L進行排序:
方法1.用List的成員函數sort進行排序
方法2.用built-in函數sorted進行排序(從2.4開始)
這兩種方法使用起來差不多,以第一種為例進行講解:
從Python2.4開始,sort方法有了三個可選的參數,Python
Library
Reference里是這樣描述的
復制代碼代碼如下:
cmp:cmp
specifies
a
custom
comparison
function
of
two
arguments
(iterable
elements)
which
should
return
a
negative,
zero
or
positive
number
depending
on
whether
the
first
argument
is
considered
smaller
than,
equal
to,
or
larger
than
the
second
argument:
"cmp=lambda
x,y:
cmp(x.lower(),
y.lower())"
key:key
specifies
a
function
of
one
argument
that
is
used
to
extract
a
comparison
key
from
each
list
element:
"key=str.lower"
reverse:reverse
is
a
boolean
value.
If
set
to
True,
then
the
list
elements
are
sorted
as
if
each
comparison
were
reversed.In
general,
the
key
and
reverse
conversion
processes
are
much
faster
than
specifying
an
equivalent
cmp
function.
This
is
because
cmp
is
called
multiple
times
for
each
list
element
while
key
and
reverse
touch
each
element
only
once.
以下是sort的具體實例。
實例1:
復制代碼代碼如下:
>>>L
=
[2,3,1,4]
>>>L.sort()
>>>L
>>>[1,2,3,4]
實例2:
復制代碼代碼如下:
>>>L
=
[2,3,1,4]
>>>L.sort(reverse=True)
>>>L
>>>[4,3,2,1]
實例3:
復制代碼代碼如下:
>>>L
=
[('b',2),('a',1),('c',3),('d',4)]
>>>L.sort(cmp=lambda
x,y:cmp(x[1],y[1]))
>>>L
>>>[('a',
1),
('b',
2),
('c',
3),
('d',
4)]
實例4:
復制代碼代碼如下:
>>>L
=
[('b',2),('a',1),('c',3),('d',4)]
>>>L.sort(key=lambda
x:x[1])
>>>L
>>>[('a',
1),
('b',
2),
('c',
3),
('d',
4)]
實例5:
復制代碼代碼如下:
>>>L
=
[('b',2),('a',1),('c',3),('d',4)]
>>>import
operator
>>>L.sort(key=operator.itemgetter(1))
>>>L
>>>[('a',
1),
('b',
2),
('c',
3),
('d',
4)]
實例6:(DSU方法:Decorate-Sort-Undercorate)
復制代碼代碼如下:
>>>L
=
[('b',2),('a',1),('c',3),('d',4)]
>>>A
=
[(x[1],i,x)
for
i,x
in
enumerate(L)]
#i
can
confirm
the
stable
sort
>>>A.sort()
>>>L
=
[s[2]
for
s
in
A]
>>>L
>>>[('a',
1),
('b',
2),
('c',
3),
('d',
4)]
以上給出了6中對List排序的方法,其中實例3.4.5.6能起到對以List
item中的某一項
為比較關鍵字進行排序.
效率比較:
復制代碼代碼如下:
cmp
<
DSU
<
key
通過實驗比較,方法3比方法6要慢,方法6比方法4要慢,方法4和方法5基本相當
多關鍵字比較排序:
實例7:
復制代碼代碼如下:
>>>L
=
[('d',2),('a',4),('b',3),('c',2)]
>>>
L.sort(key=lambda
x:x[1])
>>>
L
>>>[('d',
2),
('c',
2),
('b',
3),
('a',
4)]
我們看到,此時排序過的L是僅僅按照第二個關鍵字來排的,如果我們想用第二個關鍵字
排過序後再用第一個關鍵字進行排序呢?有兩種方法
實例8:
復制代碼代碼如下:
>>>
L
=
[('d',2),('a',4),('b',3),('c',2)]
>>>
L.sort(key=lambda
x:(x[1],x[0]))
>>>
L
>>>[('c',
2),
('d',
2),
('b',
3),
('a',
4)]
實例9:
復制代碼代碼如下:
>>>
L
=
[('d',2),('a',4),('b',3),('c',2)]
>>>
L.sort(key=operator.itemgetter(1,0))
>>>
L
>>>[('c',
2),
('d',
2),
('b',
3),
('a',
4)]
為什麼實例8能夠工作呢?原因在於tuple是的比較從左到右之一比較的,比較完第一個,如果
相等,比較第二個
㈡ 問一下關於python list的問題 請問如何比較兩個LIST里數的大小
為什麼b[0]可以小於等於而其他都是小於,還有A,B是否都是升序的?
以下是最一般的處理:
c=[]
prev=0
for i in B:
c.append(0)
for j in A:
if j>=prev and i>j:
c[-1]+=1
prev=i
㈢ 如何使用python將大量數據導出到Excel中的小技巧
何使用python將大量數據導出到Excel中的小技巧
(1) 問題描述:為了更好地展示數據,Excel格式的數據文件往往比文本文件更具有優勢,但是具體到python中,該如何導出數據到Excel呢?如果碰到需要導出大量數據又該如何操作呢?本文主要解決以上兩個問題。
(2)具體步驟如下:
1.第一步,安裝openpyxl,
使用pip install openpyxl即可,但是在windows下安裝的是2.2.6版本,但是centos自動安裝的是4.1版本,(多謝海哥的提醒)。
寫的代碼在windows下運行沒問題,但centos上卻報錯了,說是ew=ExcelWriter(workbook=wb)少提供一個參數,於是果斷在237伺服器上我已安裝2.2.6版本的,問題解決。
pip install openpyxl==2.2.6
2.第二步,哈哈,沒有啦,廢話不說了,直接上代碼,ps,代碼中包含xlwt和openpyxl的兩個實現版本。
(3)擴展閱讀:通過查閱資料,發現網上眾說紛紜,總結起來有如下幾點:
python Excel相關的操作的mole lib有兩組,一組是xlrd、xlwt、xlutils,另一組是openpyxl,
但是前一組(xlrd,xlwt)比較老,只能處理由Excel 97-2003 或者Excel 97 以前版本生成的xls格式的excel文件,xlwt甚至不支持07版以後的excel,這個格式excel文件一般來說,最大隻能支持256列或者65536行的excel文件。
因此面對需要導出大量數據到excel的情況,你將有如下三種選擇,(1)換一種存儲格式,如保存為CSV文件 (2)使用openpyxl—,因為它支持對Excel 2007+ xlsx/xlsm format的處理 (3)win32 COM (Windows only)
當然,我們要直面困難了,為了更好地展示數據給產品和用戶,我們依然選擇的第二種。
ps,非常lucky,一番搜索後我找到了openpyxl,支持07+的excel,一直有人在維護,文檔清晰易讀,參照Tutorial和API文檔很快就能上手,就是它了~
(4)閑話少說,直接上代碼,敬請參考
# coding:utf-8
'''
# 希望對大家有幫助哈,請多提問題
create by yaoyz
date: 2017/01/24
'''
import xlrd
import xlwt
# workbook相關
from openpyxl.workbook import Workbook
# ExcelWriter,封裝了很強大的excel寫的功能
from openpyxl.writer.excel import ExcelWriter
# 一個eggache的數字轉為列字母的方法
from openpyxl.utils import get_column_letter
from openpyxl.reader.excel import load_workbook
class HandleExcel():
'''Excel相關操作類'''
def __init__(self):
self. head_row_labels = [u'學生ID',u'學生姓名',u'聯系方式',u'知識點ID',u'知識點名稱']
"""
function:
讀出txt文件中的每一條記錄,把它保存在list中
Param:
filename: 要讀出的文件名
Return:
res_list: 返回的記錄的list
"""
def read_from_file(self,filename):
res_list=[]
file_obj=open(filename,"r")
for line in file_obj.readlines():
res_list.append(line)
file_obj.close()
return res_list
"""
function:
讀出*.xlsx中的每一條記錄,把它保存在data_dic中返回
Param:
excel_name: 要讀出的文件名
Return:
data_dic: 返回的記錄的dict
"""
def read_excel_with_openpyxl(self, excel_name="testexcel2007.xlsx"):
# 讀取excel2007文件
wb = load_workbook(filename=excel_name)
# 顯示有多少張表
print "Worksheet range(s):" , wb.get_named_ranges()
print "Worksheet name(s):" , wb.get_sheet_names()
# 取第一張表
sheetnames = wb.get_sheet_names()
ws = wb.get_sheet_by_name(sheetnames[0])
# 顯示表名,錶行數,表列數
print "Work Sheet Titile:" ,ws.title
print "Work Sheet Rows:" ,ws.get_highest_row()
print "Work Sheet Cols:" ,ws.get_highest_column()
# 獲取讀入的excel表格的有多少行,有多少列
row_num=ws.get_highest_row()
col_num=ws.get_highest_column()
print "row_num: ",row_num," col_num: ",col_num
# 建立存儲數據的字典
data_dic = {}
sign=1
# 把數據存到字典中
for row in ws.rows:
temp_list=[]
# print "row",row
for cell in row:
print cell.value,
temp_list.append(cell.value)
print ""
data_dic[sign]=temp_list
sign+=1
print data_dic
return data_dic
"""
function:
讀出*.xlsx中的每一條記錄,把它保存在data_dic中返回
Param:
records: 要保存的,一個包含每一條記錄的list
save_excel_name: 保存為的文件名
head_row_stu_arrive_star:
Return:
data_dic: 返回的記錄的dict
"""
def write_to_excel_with_openpyxl(self,records,head_row,save_excel_name="save.xlsx"):
# 新建一個workbook
wb = Workbook()
# 新建一個excelWriter
ew = ExcelWriter(workbook=wb)
# 設置文件輸出路徑與名稱
dest_filename = save_excel_name.decode('utf-8')
# 第一個sheet是ws
ws = wb.worksheets[0]
# 設置ws的名稱
ws.title = "range names"
# 寫第一行,標題行
for h_x in range(1,len(head_row)+1):
h_col=get_column_letter(h_x)
#print h_col
ws.cell('%s%s' % (h_col, 1)).value = '%s' % (head_row[h_x-1])
# 寫第二行及其以後的那些行
i = 2
for record in records:
record_list=str(record).strip().split(" ")
for x in range(1,len(record_list)+1):
col = get_column_letter(x)
ws.cell('%s%s' % (col, i)).value = '%s' % (record_list[x-1].decode('utf-8'))
i += 1
# 寫文件
ew.save(filename=dest_filename)
"""
function:
測試輸出Excel內容
讀出Excel文件
Param:
excel_name: 要讀出的Excel文件名
Return:
無
"""
def read_excel(self,excel_name):
workbook=xlrd.open_workbook(excel_name)
print workbook.sheet_names()
# 獲取所有sheet
print workbook.sheet_names() # [u'sheet1', u'sheet2']
sheet2_name = workbook.sheet_names()[1]
# 根據sheet索引或者名稱獲取sheet內容
sheet2 = workbook.sheet_by_index(1) # sheet索引從0開始
sheet2 = workbook.sheet_by_name('Sheet1')
# sheet的名稱,行數,列數
print sheet2.name,sheet2.nrows,sheet2.ncols
# 獲取整行和整列的值(數組)
rows = sheet2.row_values(3) # 獲取第四行內容
cols = sheet2.col_values(2) # 獲取第三列內容
print rows
print cols
# 獲取單元格內容
print sheet2.cell(1,0).value
print sheet2.cell_value(1,0)
print sheet2.row(1)[0].value
# 獲取單元格內容的數據類型
print sheet2.cell(1,0).ctype
# 通過名稱獲取
return workbook.sheet_by_name(u'Sheet1')
"""
function:
設置單元格樣式
Param:
name: 字體名字
height: 字體高度
bold: 是否大寫
Return:
style: 返回設置好的格式對象
"""
def set_style(self,name,height,bold=False):
style = xlwt.XFStyle() # 初始化樣式
font = xlwt.Font() # 為樣式創建字體
font.name = name # 'Times New Roman'
font.bold = bold
font.color_index = 4
font.height = height
borders= xlwt.Borders()
borders.left= 6
borders.right= 6
borders.top= 6
borders.bottom= 6
style.font = font
style.borders = borders
return style
"""
function:
按照 設置單元格樣式 把計算結果由txt轉變為Excel存儲
Param:
dataset:要保存的結果數據,list存儲
Return:
將結果保存為 excel對象中
"""
def write_to_excel(self, dataset,save_excel_name,head_row):
f = xlwt.Workbook() # 創建工作簿
# 創建第一個sheet:
# sheet1
count=1
sheet1 = f.add_sheet(u'sheet1', cell_overwrite_ok=True) # 創建sheet
# 首行標題:
for p in range(len(head_row)):
sheet1.write(0,p,head_row[p],self.set_style('Times New Roman',250,True))
default=self.set_style('Times New Roman',200,False) # define style out the loop will work
for line in dataset:
row_list=str(line).strip("
").split(" ")
for pp in range(len(str(line).strip("
").split(" "))):
sheet1.write(count,pp,row_list[pp].decode('utf-8'),default)
count+=1
f.save(save_excel_name) # 保存文件
def run_main_save_to_excel_with_openpyxl(self):
print "測試讀寫2007及以後的excel文件xlsx,以方便寫入文件更多數據"
print "1. 把txt文件讀入到內存中,以list對象存儲"
dataset_list=self.read_from_file("test_excel.txt")
'''test use openpyxl to handle EXCEL 2007'''
print "2. 把文件寫入到Excel表格中"
head_row_label=self.head_row_labels
save_name="test_openpyxl.xlsx"
self.write_to_excel_with_openpyxl(dataset_list,head_row_label,save_name)
print "3. 執行完畢,由txt格式文件保存為Excel文件的任務"
def run_main_save_to_excel_with_xlwt(self):
print " 4. 把txt文件讀入到內存中,以list對象存儲"
dataset_list=self.read_from_file("test_excel.txt")
'''test use xlwt to handle EXCEL 97-2003'''
print " 5. 把文件寫入到Excel表格中"
head_row_label=self.head_row_labels
save_name="test_xlwt.xls"
self.write_to_excel_with_openpyxl(dataset_list,head_row_label,save_name)
print "6. 執行完畢,由txt格式文件保存為Excel文件的任務"
if __name__ == '__main__':
print "create handle Excel Object"
obj_handle_excel=HandleExcel()
# 分別使用openpyxl和xlwt將數據寫入文件
obj_handle_excel.run_main_save_to_excel_with_openpyxl()
obj_handle_excel.run_main_save_to_excel_with_xlwt()
'''測試讀出文件,注意openpyxl不可以讀取xls的文件,xlrd不可以讀取xlsx格式的文件'''
#obj_handle_excel.read_excel_with_openpyxl("testexcel2003.xls") # 錯誤寫法
#obj_handle_excel.read_excel_with_openpyxl("testexcel2003.xls") # 錯誤寫法
obj_handle_excel.read_excel("testexcel2003.xls")
obj_handle_excel.read_excel_with_openpyxl("testexcel2007.xlsx")
㈣ python 讀取txt,將每行存為list
import pandas as pd
df=pd.read_table('d:/data.txt',sep=":",encoding='gbk',header=None)
df.columns=['a','b']
df['b']=df.b.map(lambda x:x[1:-1].replace("'",'').replace(' ',''))
df1=pd.concat([df.a,df.b.str.split(',',expand=True)],axis=1)
df1=df1.set_index('a')
df1=df1.stack().reset_index().drop('level_1',axis=1)
df1.to_excel('d:/out_data.xlsx',header=None,index=None)
㈤ python3 對象 |字典|json|yaml|字元串 相互轉化
在研究 k8s 的yaml 配置文件的時候,我總擔心自己一不小心 會寫錯,所以我嚮往 使用將對象 序列化 yaml 的形式,
其實 python object 可以 直接 轉 yaml ,甚至也可以 直接 轉成yaml文件!!!
這里 會經常用到幾個 函數 vars() ast.
我們先嘗試用最笨的方法 實現 object到yaml 的轉化
在python對象 convert to dict 的形式,使用 vars()函數
然後 dict convert to json 使用 json.mps(dict)函數
然後 json converte to yaml 使用 ya= yaml.load(json.mps(dict)) 然後
再 yaml.safe_mp(ya,default_flow_style=False)
至此我們看到 從 python Object ---> dict ----> json ---> yaml 的轉化
其中 obj dict json yaml 轉 string ,只要 str()函數即可,或者 str(vars())結合
yaml 格式 寫入到文件 ,需要注意的是, open()函數 的mode 一定要是 'w' ,不能是』wb', b代表是二進制寫入
yaml 寫入的是dict str,使用 『wb' 會報錯,[yaml TypeError: a bytes-like object is required, not 'str']
【出現該錯誤往往是通過open()函數打開文本文件時,使用了『rb』屬性,如:fileHandle=open(filename,'rb'),則此時是通過二進制方式打開文件的,所以在後面處理時如果使用了str()函數,就會出現該錯誤,該錯誤不會再python2中出現。
具體解決方法有以下兩種:
第一種,在open()函數中使用『r』屬性,即文本方式讀取,而不是『rb』,以二進制文件方式讀取,可以直接解決問題。
第二種,在open()函數中使用『rb』,可以在使用之前進行轉換,有以下實例,來自: http://stackoverflow.com/questions/33054527/python-3-5-typeerror-a-bytes-like-object-is-required-not-str 】
其實 python object 可以 直接 轉 yaml ,甚至也可以 直接 轉成yaml文件!!!
比如我已經定義了一個 Dog python class,他有 好幾個屬性 並已經賦值初始化了
另外生成 yaml 對象
生成yaml文件
結果是
反過來 yaml ----> json ---> 持久化 json 文件 indent=1屬性是為了讓 json 不以單行展示,而是展開
注意的是 python 的 dict 和set 很相似 ,都是 { }, set 里是list, dict 是鍵值對
【# set object is not JSON serializable [plicate]
】
打開 demo.json
yaml ---> dict
yaml ---> python object
json --> dict
json.loads()
dict--> json
json.jumps()
str ---> dict
newdict=dict(str)
json -- > python object
一個python object無法直接與json轉化,只能先將對象轉化成dictionary,再轉化成json;對json,也只能先轉換成dictionary,再轉化成object,通過實踐,源碼如下:
yaml --> python object
對yaml,也只能先轉換成json --->dictionary,再轉化成object,通過實踐,源碼如下:
dict -- ->python object
python對象 默認都有一個 私有的屬性 dict 取值 就是 object的 字典形式, 賦值就就可以給對象屬性對應賦值
例如json 轉 對象
對象 轉 json
Python之dict(或對象)與json之間的互相轉化
在Python語言中,json數據與dict字典以及對象之間的轉化,是必不可少的操作。
dict字典轉json數據
對象轉json數據
json數據轉成dict字典
json數據轉成對象
json的load()與mp()方法的使用
mp()方法的使用
㈥ Python學習之惰性求值
惰性求值,也就是延遲求值,表達式不會在它被綁定到變數之後就立即求值,而是等用到時再求值。這個特性可以解決一些巨大甚至無限的集合列表,如菲波那切數列、幾十G的文件等等。延遲求值的一個好處是能夠建立可計算的無限列表而沒有妨礙計算的無限循環或大小問題。
Python中的很多方法沒有直接返回列表,而是返回了一個可迭代的generator
(生成器)對象,這便是python的惰性求值,因為在創建一個很大的列表時,對內存的開銷非常大,太大時python會直接報錯,舉個:chestnut::range()方法是產生一個指定范圍列表,在Python3之前,該方法直接產生一個列表,xrange()產生一個生成器:
>>>xrange(100)
xrange(100)
>>>range(100)
[0, 1, 2, 3,
4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,
22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38,
39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55,
56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72,
73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89,
90, 91, 92, 93, 94, 95, 96, 97, 98, 99]
當參數裡面的值足夠大時,range()產生了一個巨大的列表,這是內存會吃不消,等待一段時間後程序會直接被Kill掉:
>>>foriinrange(999999999999):
...
printi
...
Killed:
9
占滿內存
用xrange()方法就不回出現這種問題,並且可以一直運行:
>>>foriinxrange(999999999999):
...
printi
...
0
1
2
3
4
5
6
7
8
9
10...
在Python3中range已經被改為了xrange,所以在python3中可以放心使用range().
惰性求值不要求你事先准備好整個迭代過程中所有的元素。迭代器僅僅在迭代至某個元素時才計算該元素,而在這之前或之後,元素可以不存在或者被銷毀
還有前文所說的list comprehension語句,在兩邊放上[],會產生別表,如果數據源很長則會報內存錯誤:
>>>
print [iforiinrange(9999999999999999)]
Python(1627,0x7fffe5b713c0)
malloc: *** mach_vm_map(size=80000000000000000) failed
(errorcode=3)
***error:
can't allocate region
***seta
breakpointinmalloc_error_breaktodebug
Traceback
(most recentcalllast):
File "",
line 1,in<</span>mole>
MemoryError
這樣直接產生列表沒有效率,為了創建生成器對象,可以在list
comprehension兩邊放上(),這樣它就有了惰性求值的特性。
>>>
print((ifori
inrange(99999999999999)))
使用next()內建函數訪問生成器里的元素:
num =
(iforiinrange(5))
>>>
num
>>>>
next(num)
0
>>>
next(num)
1
>>>
for j in range(4):
...
print(next(num))
...
2
3
4
Traceback
(most recent call last):
File "",
line 2,in<</span>mole>
StopIteration
當訪問到最後元素時,再調用next(),Python將會拋出StopIteration異常。Python正是根據是否檢查到這個異常來決定是否停止迭代。
step1 =
someLongOperation1()step2 = someLongOperation2()step3 =
concatenate(step1, step2)
以上代碼需要分別執行一二兩步操作,第三步用到一二兩步的結果,在Pyhton中會有序的執行這些函數:首先是someLongOperation1,然後someLongOperation2,最後concatenate,如果確保沒有函數修改或依賴於全局變數,第一二步可以被並行執行。假設我們不想並行運行這兩個函數,我們只在其他函數依賴於step1和step2時才需要執行這兩個函數。我們甚至在concatenate調用之前都不必執行他們,可以把他們的求值延遲到concatenate函數內實際用到他們的位置。如果函數中用到了if分支語句,條件無關step1和step2則可以盡量將判斷條件放前面以減少不必要的計算:
step1 =
someLongOperation1()
step2 =
someLongOperation2()ifcondition:
step3 =
concatenate(step1, step2)
換為:ifcondition:
step1 =
someLongOperation1()
step2 =
someLongOperation2()
step3 =
concatenate(step1, step2)
如果concatenate是一個帶有條件分支的函數並且有的分支中只用了兩個參數中的一個,另一個參數就永遠沒有必要被求值。
㈦ python的setdistance什麼用
在Python set是基本數據類型的一種集合類型,它有可變集合(set())和不可變集合(frozenset)兩種。
創建集合set、集合set添加、集合刪除、交集、並集、差集培悶的操作都是非常實用的方法。
set 是一個無序的元素集合,支持並、交、差及對稱差等數學運算, 但由於 set 不記錄元素位置,因此不支持索引、分片等類序列的操作。
tuple算是list和str的雜合(雜交的都有自己的優勢,上一節的末後已經顯示了),那麼set則可以堪稱是list和dict的雜合.
set擁有類似dict的特點:可以用{}花括弧來定義;其中的元素沒有序列,也就是是非序列類型的數據;而且,set中的元素不可重復,這就類似dict的鍵.
set也有一點list的特點:有一種集合可以原處修改.
一:創建集合set:
python set類是在python的sets模塊中,大家現在使用的python2.3中,不需要導入sets模塊可以直接創建集合。
>>>set('boy')
set(['y', 'b', 'o'])
二:集合添加、刪除
集合的添加有兩種常用方法,分別是add和update。集合add方法:是把要傳入的元素做為一個整個添加到集合中,例如:
>>> a = set('boy')
>>> a.add('python')
>>> a
set(['y', 'python', 'b', 'o'])
集合update方法:是把要傳譽肆入的元素拆分,做為個體傳入到集合中,例如:
>>> a = set('boy')
>>> a.update('python')
>>> a
set(['b', 'h', 'o', 'n', 'p', 't', 'y'])
集合刪除操作方法:remove
set(['y', 'python', 'b', 'o'])
>>> a.remove('python')
>>> a
set(['y', 'b', 'o'])
set的常用方法
add, update
>>> help(set.add)
Help on method_descriptor:
add(...)
Add an element to a set.
This has no effect if the element is already present.
下面在交互模式這個最好的實驗室裡面做實驗:
>>> a_set = {} #我想當然地認為這樣也可以建立一個set
>>> a_set.add("qiwsir") #報錯.看看錯誤信息,居然告訴我dict沒有add.我分明建立的是set呀.
Traceback (most recent call last):
File "", line 1, in
AttributeError: 'dict' object has no attribute 'add'
>>> type(a_set) #type之後發現,計算機認為我建立的是一個dict
特別說明一下,{}這個東西,在dict和set中都用.但是,如上面的方法建立的是dict,不是set.這是python規定的.要建立set,只能用慶中轎前面介紹的方法了.
>>> a_set = {'a','i'} #這回就是set了吧
>>> type(a_set)
#果然
>>> a_set.add("qiwsir") #增加一個元素
>>> a_set #原處修改,即原來的a_set引用對象已經改變
set(['i', 'a', 'qiwsir'])
>>> b_set = set("python")
>>> type(b_set)
>>> b_set
set(['h', 'o', 'n', 'p', 't', 'y'])
>>> b_set.add("qiwsir")
>>> b_set
set(['h', 'o', 'n', 'p', 't', 'qiwsir', 'y'])
>>> b_set.add([1,2,3]) #報錯.list是不可哈希的,集合中的元素應該是hashable類型。
Traceback (most recent call last):
File "", line 1, in
TypeError: unhashable type: 'list'
>>> b_set.add('[1,2,3]') #可以這樣!
>>> b_set
set(['[1,2,3]', 'h', 'o', 'n', 'p', 't', 'qiwsir', 'y'])
除了上面的增加元素方法之外,還能夠從另外一個set中合並過來元素,方法是set.update(s2)
>>> help(set.update)
update(...)
Update a set with the union of itself and others.
>>> s1
set(['a', 'b'])
>>> s2
set(['github', 'qiwsir'])
>>> s1.update(s2) #把s2的元素並入到s1中.
>>> s1 #s1的引用對象修改
set(['a', 'qiwsir', 'b', 'github'])
>>> s2 #s2的未變
set(['github', 'qiwsir'])
如果僅僅是這樣的操作,容易誤以為update方法的參數只能是集合。非也。看文檔中的描述,這個方法的作用是用原有的集合自身和其它的什麼東西構成的新集合更新原來的集合。這句話有點長,可以多讀一遍。分解開來,可以理解為:others是指的作為參數的不可變對象,將它和原來的集合組成新的集合,用這個新集合替代原來的集合。舉例:
>>> s2.update("goo")
>>> s2
set(['github', 'o', 'g', 'qiwsir'])
>>> s2.update((2,3))
>>> s2
set([2, 3, 'g', 'o', 'github', 'qiwsir'])
所以,文檔的寓意還是比較深刻的。
pop, remove, discard, clear
>>> help(set.pop)
pop(...)
Remove and return an arbitrary set element.
Raises KeyError if the set is empty.
>>> b_set
set(['[1,2,3]', 'h', 'o', 'n', 'p', 't', 'qiwsir', 'y'])
>>> b_set.pop() #從set中任意選一個刪除,並返回該值
'[1,2,3]'
>>> b_set.pop()
'h'
>>> b_set.pop()
'o'
>>> b_set
set(['n', 'p', 't', 'qiwsir', 'y'])
>>> b_set.pop("n") #如果要指定刪除某個元素,報錯了.
Traceback (most recent call last):
File "", line 1, in
TypeError: pop() takes no arguments (1 given)
set.pop()是從set中任意選一個元素,刪除並將這個值返回.但是,不能指定刪除某個元素.報錯信息中就告訴我們了,pop()不能有參數.此外,如果set是空的了,也報錯.這條是幫助信息告訴我們的,看官可以試試.要刪除指定的元素,怎麼辦?
>>> help(set.remove)
remove(...)
Remove an element from a set; it must be a member.
If the element is not a member, raise a KeyError.
set.remove(obj)中的obj,必須是set中的元素,否則就報錯.試一試:
>>> a_set
set(['i', 'a', 'qiwsir'])
>>> a_set.remove("i")
>>> a_set
set(['a', 'qiwsir'])
>>> a_set.remove("w")
Traceback (most recent call last):
File "", line 1, in
KeyError: 'w'
跟remove(obj)類似的還有一個discard(obj):
>>> help(set.discard)
discard(...)
Remove an element from a set if it is a member.
If the element is not a member, do nothing
與help(set.remove)的信息對比,看看有什麼不同.discard(obj)中的obj如果是set中的元素,就刪除,如果不是,就什麼也不做,do nothing.新聞就要對比著看才有意思呢.這里也一樣.
>>> a_set.discard('a')
>>> a_set
set(['qiwsir'])
>>> a_set.discard('b')
>>>
在刪除上還有一個絕殺,就是set.clear(),它的功能是:Remove all elements from this set.(看官自己在交互模式下help(set.clear))
>>> a_set
set(['qiwsir'])
>>> a_set.clear()
>>> a_set
set([])
>>> bool(a_set) #空了,bool一下返回False.
㈧ 如何使用python 統計網站訪問量並生成報表
統計網站訪問量
統計出每個IP的訪問量有多少?(從日誌文件中查找)
#!/usr/bin/env python
#!coding=utf-8
list = []
f = file('/tmp/1.log')
str1 = f.readlines()
f.close()
for i in str1:
ip = i.split()[0] //split()通過指定分隔符對字元串進行切片,默認為所有的空字元;split分隔後是一個列表,[0]表示取其第一個元素;
list.append(ip)//追加
list_num = set(list)
for j in list_num:
num = list.count(j)
print '%s : %s' %(j,num)
生成報表
#_*_coding:utf-8_*_
import Mysqldb
import xlwt
from datetime import datetime
def get_data(sql):
# 創建資料庫連接.
conn = MySQLdb.connect(host='127.0.0.1',user='root'\
,passwd='123456',db='test',port=3306,charset='utf8')
# 創建游標
cur = conn.cursor()
# 執行查詢,
cur.execute(sql)
# 由於查詢語句僅會返回受影響的記錄條數並不會返回資料庫中實際的值,所以此處需要fetchall()來獲取所有內容。
result = cur.fetchall()
#關閉游標
cur.close()
#關閉資料庫連接
conn.close
# 返給結果給函數調用者。
return result
def write_data_to_excel(name,sql):
# 將sql作為參數傳遞調用get_data並將結果賦值給result,(result為一個嵌套元組)
result = get_data(sql)
# 實例化一個Workbook()對象(即excel文件)
wbk = xlwt.Workbook()
# 新建一個名為Sheet1的excel sheet。此處的cell_overwrite_ok =True是為了能對同一個單元格重復操作。
sheet = wbk.add_sheet('Sheet1',cell_overwrite_ok=True)
# 獲取當前日期,得到一個datetime對象如:(2016, 8, 9, 23, 12, 23, 424000)
today = datetime.today()
# 將獲取到的datetime對象僅取日期如:2016-8-9
today_date = datetime.date(today)
# 遍歷result中的沒個元素。
for i in xrange(len(result)):
#對result的每個子元素作遍歷,
for j in xrange(len(result[i])):
#將每一行的每個元素按行號i,列號j,寫入到excel中。
sheet.write(i,j,result[i][j])
# 以傳遞的name+當前日期作為excel名稱保存。
wbk.save(name+str(today_date)+'.xls')
# 如果該文件不是被import,則執行下面代碼。
if __name__ == '__main__':
#定義一個字典,key為對應的數據類型也用作excel命名,value為查詢語句
db_dict = {'test':'select * from student'}
# 遍歷字典每個元素的key和value。
for k,v in db_dict.items():
# 用字典的每個key和value調用write_data_to_excel函數。
write_data_to_excel(k,v)
㈨ python class 內的 next(),last(),set() 寫法
classSchele(calender):
def__init__(self,date,usage,owner):
self.usage=usage
self.owner=owner
#保存所有的日期
self._list=[date,]
self.current=date
defadd(self,date):
self._list.append(date)
#假定date對象是支持比較的
self._list.sort()
defset(self,date):
ifdatenotinself._list:
如早搜self.add(date)
self.current=date
def睜肢next(self):
渣歷index=self._list.index(self.current)+1
ifindex>=len(self._list):
print"nonext"
else:
returnself._list[index]
last類似,略
㈩ python中ls【】【】是什麼意思
【CSDN 編者按】Python 風頭正盛,未來一段時間內想必也會是熱門編程語言之一。因此,熟練掌握 Python 對開發者來說極其重要,說不定能給作為開發者的你帶來意想不到的財富。
作者 | Sebastian Opałczyński
編譯 | 彎月 責編 | 張文
出品 | CSDN(ID:CSDNnews)
在本文中,我們來看一看日常工作中經常使用的一些 Python 小技巧。
集合
開發人員常常忘記 Python 也有集合數據類型,大家都喜歡使用列表處理一切。
集合(set)是什麼?簡單來說就是:集合是一組無序事物的匯集,不包含重復元素。
如果你熟練掌握集合及其邏輯,那麼很多問題都可以迎刃而解。舉個例子,如何獲取一個單詞中出現的字母?
myword = "NanananaBatman"set(myword){'N', 'm', 'n', 'B', 'a', 't'}
就這么簡單,問題解決了,這個例子就來自 Python 的官方文檔,大可不必過於驚訝。
再舉一個例子,如何獲取一個列表的各個元素,且不重復?
# first you can easily change set to list and other way aroundmylist = ["a", "b", "c","c"]# let's make a set out of itmyset = set(mylist)# myset will be:{'a', 'b', 'c'}# and, it's already iterable so you can do:for element in myset:print(element)# but you can also convert it to list again:mynewlist = list(myset)# and mynewlist will be:['a', 'b', 'c']
我們可以看到,「c」元素不再重復出現了。只有一個地方你需要注意,mylist 與 mynewlist 之間的元素順序可能會有所不同:
mylist = ["c", "c", "a","b"]mynewlist = list(set(mylist))# mynewlist is:['a', 'b', 'c']
可以看出,兩個列表的元素順序不同。
下面,我們來進一步深入。
假設某些實體之間有一對多的關系,舉個更加具體的例子:用戶與許可權。通常,一個用戶可以擁有多個許可權。現在假設某人想要修改多個許可權,即同時添加和刪除某些許可權,應當如何解決這個問題?
# this is the set of permissions before change;original_permission_set = {"is_admin","can_post_entry", "can_edit_entry", "can_view_settings"}# this is new set of permissions;new_permission_set = {"can_edit_settings","is_member", "can_view_entry", "can_edit_entry"}# now permissions to add will be:new_permission_set.difference(original_permission_set)# which will result:{'can_edit_settings', 'can_view_entry', 'is_member'}# As you can see can_edit_entry is in both sets; so we do notneed# to worry about handling it# now permissions to remove will be:original_permission_set.difference(new_permission_set)# which will result:{'is_admin', 'can_view_settings', 'can_post_entry'}# and basically it's also true; we switched admin to member, andadd# more permission on settings; and removed the post_entrypermission
總的來說,不要害怕使用集合,它們能幫助你解決很多問題,更多詳情,請參考 Python 官方文檔。
日歷
當開發與日期和時間有關的功能時,有些信息可能非常重要,比如某一年的這個月有多少天。這個問題看似簡單,但是我相信日期和時間是一個非常有難度的話題,而且我覺得日歷的實現問題非常多,簡直就是噩夢,因為你需要考慮大量的極端情況。
那麼,究竟如何才能找出某個月有多少天呢?
import calendarcalendar.monthrange(2020, 12)# will result:(1, 31)# BUT! you need to be careful here, why? Let's read thedocumentation:help(calendar.monthrange)# Help on function monthrange in mole calendar:# monthrange(year, month)# Return weekday (0-6~ Mon-Sun) and number of days (28-31) for# year, month.# As you can see the first value returned in tuple is a weekday,# not the number of the first day for a given month; let's try# to get the same for 2021calendar.monthrange(2021, 12)(2, 31)# So this basically means that the first day of December 2021 isWed# and the last day of December 2021 is 31 (which is obvious,cause# December always has 31 days)# let's play with Februarycalendar.monthrange(2021, 2)(0, 28)calendar.monthrange(2022, 2)(1, 28)calendar.monthrange(2023, 2)(2, 28)calendar.monthrange(2024, 2)(3, 29)calendar.monthrange(2025, 2)(5, 28)# as you can see it handled nicely the leap year;
某個月的第一天當然非常簡單,就是 1 號。但是,「某個月的第一天是周X」,如何使用這條信息呢?你可以很容易地查到某一天是周幾:
calendar.monthrange(2024, 2)(3, 29)# means that February 2024 starts on Thursday# let's define simple helper:weekdays = ["Monday", "Tuesday","Wednesday", "Thursday", "Friday","Saturday", "Sunday"]# now we can do something like:weekdays[3]# will result in:'Thursday'# now simple math to tell what day is 15th of February 2020:offset = 3 # it's thefirst value from monthrangefor day in range(1, 29):print(day,weekdays[(day + offset - 1) % 7])1 Thursday2 Friday3 Saturday4 Sunday...18 Sunday19 Monday20 Tuesday21 Wednesday22 Thursday23 Friday24 Saturday...28 Wednesday29 Thursday# which basically makes sense;
也許這段代碼不適合直接用於生產,因為你可以使用 datetime 更容易地查找星期:
from datetime import datetimemydate = datetime(2024, 2, 15)datetime.weekday(mydate)# will result:3# or:datetime.strftime(mydate, "%A")'Thursday'
總的來說,日歷模塊有很多有意思的地方,值得慢慢學習:
# checking if year is leap:calendar.isleap(2021) #Falsecalendar.isleap(2024) #True# or checking how many days will be leap days for given yearspan:calendar.leapdays(2021, 2026) # 1calendar.leapdays(2020, 2026) # 2# read the help here, as range is: [y1, y2), meaning that second# year is not included;calendar.leapdays(2020, 2024) # 1
枚舉有第二個參數
是的,枚舉有第二個參數,可能很多有經驗的開發人員都不知道。下面我們來看一個例子:
mylist = ['a', 'b', 'd', 'c', 'g', 'e']for i, item in enumerate(mylist):print(i, item)# Will give:0 a1 b2 d3 c4 g5 e# but, you can add a start for enumeration:for i, item in enumerate(mylist, 16):print(i, item)# and now you will get:16 a17 b18 d19 c20 g21 e
第二個參數可以指定枚舉開始的地方,比如上述代碼中的 enumerate(mylist,16)。如果你需要處理偏移量,則可以考慮這個參數。
if-else 邏輯
你經常需要根據不同的條件,處理不同的邏輯,經驗不足的開發人員可能會編寫出類似下面的代碼:
OPEN = 1IN_PROGRESS = 2CLOSED = 3def handle_open_status():print('Handling openstatus')def handle_in_progress_status():print('Handling inprogress status')def handle_closed_status():print('Handling closedstatus')def handle_status_change(status):if status == OPEN:handle_open_status()elif status ==IN_PROGRESS:handle_in_progress_status()elif status == CLOSED:handle_closed_status()handle_status_change(1) #Handling open statushandle_status_change(2) #Handling in progress statushandle_status_change(3) #Handling closed status
雖然這段代碼看上去也沒有那麼糟,但是如果有 20 多個條件呢?
那麼,究竟應該怎樣處理呢?
from enum import IntEnumclass StatusE(IntEnum):OPEN = 1IN_PROGRESS = 2CLOSED = 3def handle_open_status():print('Handling openstatus')def handle_in_progress_status():print('Handling inprogress status')def handle_closed_status():print('Handling closedstatus')handlers = {StatusE.OPEN.value:handle_open_status,StatusE.IN_PROGRESS.value: handle_in_progress_status,StatusE.CLOSED.value:handle_closed_status}def handle_status_change(status):if status not inhandlers:raiseException(f'No handler found for status: {status}')handler =handlers[status]handler()handle_status_change(StatusE.OPEN.value) # Handling open statushandle_status_change(StatusE.IN_PROGRESS.value) # Handling in progress statushandle_status_change(StatusE.CLOSED.value) # Handling closed statushandle_status_change(4) #Will raise the exception
在 Python 中這種模式很常見,它可以讓代碼看起來更加整潔,尤其是當方法非常龐大,而且需要處理大量條件時。
enum 模塊
enum 模塊提供了一系列處理枚舉的工具函數,最有意思的是 Enum 和 IntEnum。我們來看個例子:
from enum import Enum, IntEnum, Flag, IntFlagclass MyEnum(Enum):FIRST ="first"SECOND ="second"THIRD ="third"class MyIntEnum(IntEnum):ONE = 1TWO = 2THREE = 3# Now we can do things like:MyEnum.FIRST ## it has value and name attributes, which are handy:MyEnum.FIRST.value #'first'MyEnum.FIRST.name #'FIRST'# additionally we can do things like:MyEnum('first') #, get enum by valueMyEnum['FIRST'] #, get enum by name
使用 IntEnum 編寫的代碼也差不多,但是有幾個不同之處:
MyEnum.FIRST == "first" # False# butMyIntEnum.ONE == 1 # True# to make first example to work:MyEnum.FIRST.value == "first" # True
在中等規模的代碼庫中,enum 模塊在管理常量方面可以提供很大的幫助。
enum 的本地化可能有點棘手,但也可以實現,我用django快速演示一下:
from enum import Enumfrom django.utils.translation import gettext_lazy as _class MyEnum(Enum):FIRST ="first"SECOND ="second"THIRD ="third"@classmethoddef choices(cls):return [(cls.FIRST.value, _('first')),(cls.SECOND.value, _('second')),(cls.THIRD.value, _('third'))# And later in eg. model definiton:some_field = models.CharField(max_length=10,choices=MyEnum.choices())
iPython
iPython 就是互動式 Python,它是一個互動式的命令行 shell,有點像 Python 解釋器。
首先,你需要安裝 iPython:
pip install ipython
接下來,你只需要在輸入命令的時候,將 Python 換成 ipython:
# you should see something like this after you start:Python 3.8.5 (default, Jul 28 2020, 12:59:40)Type 'right', 'credits' or 'license' for more informationIPython 7.18.1 -- An enhanced Interactive Python. Type '?' forhelp.In [1]:
ipython 支持很多系統命令,比如 ls 或 cat,tab 鍵可以顯示提示,而且你還可以使用上下鍵查找前面用過的命令。更多具體信息,請參見官方文檔。
參考鏈接:https://levelup.gitconnected.com/python-tricks-i-can-not-live-without-87ae6aff3af8