天天看點

python中sorted的用法append_python字元串反轉 高階函數 @property與sorted(八)詳解

(1)字元串反轉

1倒序輸出

s = 'abcde'

print(s[::-1])

#輸出: 'edcba'

2 清單reverse()操作

s = 'abcde'

lt = list(s)

lt.reverse()

print(''.join(lt))

#輸出: 'edcba'

3 二分法交換位置

s = 'abcde'

lt = list(s)

for i in range(len(l) // 2):

lt[i], lt[-(i+1)] = lt[-(i+1)], lt[i]

print(''.join(lt))

#輸出: 'edcba'

4 清單生成式

s = 'abcde'

print(''.join([s[i-1] for i in range(len(s), 0, -1)]))

#輸出: 'edcba'

5 棧的思想

s = 'abcde'

lt = list(s)

res = ''

while lt:

res += lt.pop()

print(res)

#輸出: 'edcba'

6 遞歸的思路

def res_str(s):

if len(s) == 1:

return s

head = s[0]

tail = s[1:]

return res_str(tail)+head

res_str('abcd')

#輸出: 'dcba'

(2)冒泡排序

采用循環

import numpy as np

def bubble_sort(arr):

for i in range(1,arr.size):

for j in range(arr.size-1):

if arr[j] > arr[j+1]:

arr[j],arr[j+1] = arr[j+1],arr[j]

print(arr)

arr = np.array([4,7,8,9,3,6,7,9,4,0])

bubble_sort(arr)

采用數組中的partition,用遞歸實作

import numpy as np

def quick_sort(arr):

if arr.size == 1:

return arr

_arr = np.partition(arr,1) #在索引1前面的一定是最小值

return np.append(_arr[:1],quick_sort(_arr[1:]))

quick_sort(arr)

def quick_sort2(arr):

if arr.size < 2:

return arr

_arr = np.partition(arr,1) #在索引2前面的一定是最小值

return np.append(_arr[:2],quick_sort2(_ar/r[2:]))

quick_sort2(arr)

(3)高階函數用法

map函數的用法

map : map()函數接收兩個參數,一個是函數,一個是Iterable,map将傳入的函數依次作用到序列的每個元素,并把結果作為新的Iterator傳回。

>>> list(map(str, [1, 2, 3, 4, 5, 6, 7, 8, 9]))

['1', '2', '3', '4', '5', '6', '7', '8', '9']

map()傳入的第一個參數是f,即函數對象本身。由于結果r是一個Iterator,Iterator是惰性序列,是以通過list()函數讓它把整個序列都計算出來并傳回一個list。

reduce函數的用法

reduce把一個函數作用在一個序列[x1, x2, x3, ...]上,這個函數必須接收兩個參數,reduce把結果繼續和序列的下一個元素做累積計算,其效果就是:

把序列[1, 3, 5, 7, 9]變換成整數13579,reduce就可以派上用場

from functools import reduce

>>> def func(x, y):

... return x * 10 + y

...

>>> reduce(func, [1, 3, 5, 7, 9])

13579

如果是完成字元串轉數字了,那麼就可以采用map與reduce組合

>>> from functools import reduce

>>> def func(x, y):

... return x * 10 + y

...

>>> def tran(s):

... digits = {'0': 0, '1': 1, '2': 2, '3': 3, '4': 4, '5': 5, '6': 6, '7': 7, '8': 8, '9': 9}

... return digits[s]

...

>>> reduce(func, map(tran, '13579'))

13579

>>>reduce(lambda x,y:10*x+y, map(tran,'13579')) #字元串也是可疊代的

13579

對于一般的函數表達式我們建議采用lambda函數實作,下面我們用lambda函數改寫

>>>reduce(lambda x,y: x*10+y , [1,3,5,7,9])

13579

>>>reduce(lambda x,y:10*x+y, map(int,['1','3','5','7','9']))

13579

>>>reduce(lambda x,y:10*x+y, map(int,['1','3','5','7','9']))

13579

filter過濾函數

filter()也接收一個函數和一個序列。和map()不同的是,filter()把傳入的函數依次作用于每個元素,然後根據傳回值是True還是False決定保留還是丢棄該元素。

見用filter()這個高階函數,關鍵在于正确實作一個“篩選”函數。

def not_empty(s):

return s and s.strip()

list(filter(not_empty, ['A', '', 'B', None, 'C', ' ']))

# 結果: ['A', 'B', 'C']

注意到filter()函數傳回的是一個Iterator,也就是一個惰性序列,是以要強迫filter()完成計算結果,需要用list()函數獲得所有結果并傳回list。

一般我們也會與lambda函數配合,非常友善的取代if判斷效果.

class BookViewModel:

self.publisher = book['publisher']

self.author = book['author']

self.price = book['price']

def intro(self):

intros = filter(lambda x:True if x else False,[self.author,self.publisher,self.price])

return '/'.join(str(s) for s in intros)

lambda x:True if x else False可以實作對x是否為空的判定,X存在傳回True,并保留,X不存在傳回空并排除.

注意:

join函數組合可疊代對象時,當對象中存在數字與字元串類型不同時,需要轉成統一格式再組合.一般采 取的做法是先周遊可疊代對象轉統一格式後合并. '/'.join(str(s) for s in intros)

sorted函數

Python内置的sorted()函數

>>> sorted([36, 5, -12, 9, -21])

[-21, -12, 5, 9, 36]

sorted()函數也是一個高階函數,它還可以接收一個key函數來實作自定義的排序,例如按絕對值大小排序:

>>> sorted([36, 5, -12, 9, -21], key=abs)

[5, 9, -12, -21, 36]

字元串的排序

>>> sorted(['bob', 'about', 'Zoo', 'Credit'])

['Credit', 'Zoo', 'about', 'bob']

預設情況下,對字元串排序,是按照ASCII的大小比較的,由于'Z' < 'a',結果,大寫字母Z會排在小寫字母a的前面。

sorted函數中key可以實作使用者自定義排序規則,而不僅僅限于簡單排序

>>> sorted(['bob', 'about', 'Zoo', 'Credit'], key=str.lower, reverse=True)

['Zoo', 'Credit', 'bob', 'about']

key=str.lower 按照統一小寫排序, reverse=True實作反向排序.

(4)@property

class Student(object):

@property

def score(self):

return self._score

@score.setter

def score(self, value):

if not isinstance(value, int):

raise ValueError('score must be an integer!')

if value < 0 or value > 100:

raise ValueError('score must between 0 ~ 100!')

self._score = value

把一個getter方法變成屬性,[email protected],此時,@[email protected],負責把一個setter方法變成屬性指派

>>> s = Student()

>>> s.score = 60 # OK,實際轉化為s.set_score(60)

>>> s.score # OK,實際轉化為s.get_score()

60

>>> s.score = 9999

Traceback (most recent call last):

...

ValueError: score must between 0 ~ 100!

最經典的地方是對于私有變量的存儲 , 例如密碼

class User(Base):

'''

模型屬性設定

'''

id = Column(Integer, primary_key=True)

nickname = Column(String(24), nullable=False)

_password = Column('password',String(64))

@property

def password(self): #加上 @property類似将其變為getattr

return self._password

@password.setter #負責生成哈希加密

def password(self,raw):

self._password = generate_password_hash(raw)

@[email protected],負責把一個setter方法變成屬性指派,[email protected]性self._password,通過調用 xxx.password就可擷取值

(5) setattr hasattr getattr 動态操作屬性

hasattr(object, name)

判斷一個對象裡面是否有name屬性或者name方法,傳回BOOL值,有name特性傳回True, 否則傳回False。getattr(object, name[,default])

擷取對象object的屬性或者方法,如果存在列印出來,如果不存在,列印出預設值,預設值可選。

需要注意的是,如果是傳回的對象的方法,傳回的是方法的記憶體位址.

setattr(object, name, values)

給對象的屬性指派,若屬性不存在,先建立再指派

>>> hasattr(t, "name") #判斷對象有name屬性

True

>>> hasattr(t, "run") #判斷對象有run方法

True

>>> class test():

... name="xiaohua"

... def run(self):

... return "HelloWord"

...

>>> t=test()

>>> getattr(t, "name") #擷取name屬性,存在就列印出來。

'xiaohua'

>>> getattr(t, "run") #擷取run方法,存在就列印出方法的記憶體位址。

>

>>> getattr(t, "age") #擷取一個不存在的屬性。

Traceback (most recent call last):

File "", line 1, in

AttributeError: test instance has no attribute 'age'

>>> getattr(t, "age","18") #若屬性不存在,傳回一個預設值

'18'

>>>

>>> hasattr(t, "age") #判斷屬性是否存在

False

>>> setattr(t, "age", "18") #為屬相指派,并沒有傳回值

>>> hasattr(t, "age") #屬性存在了

True

例如我們有需求儲存使用者資料

user = User()

user.name = form.name.data

user.phone_number = form.name.data

....

實際應用中常常綜合用來判斷類執行個體對象是否含有某屬性值 , 存在就擷取 ,不存在就設定

#attrs_dict以字典的形式存儲了使用者的資訊

def set_attrs(self, attrs_dict):

for key, value in attrs_dict.items():

#判斷使用者是否含有該屬性

if hasattr(self, key) and key != 'id':

#設定屬性值

setattr(self, key, value)