Python 如何傳遞運算表示式

2021-09-11 12:00:18 字數 3061 閱讀 4067

首先要說明的一下,所描述的是 python 中的運算表示式的部分,不是 python 表示式的部分。

題目如下:

給定乙個實數列表和區間,找出區間部分。

這個問題中有 2 個變數,乙個是實數列表,乙個區間。其中區間包含幾種情況:

由於區間存在多種情況,無法通過一種固定的形式去描述這個區間。

假設左邊界是 a,右邊界是 b,列表中某個變數是 x,那麼轉換成區間關係就是:

那麼如何使用一種優雅的方式獲取這種運算關係,就是要解決的乙個問題。

傳遞運算表示式在 python 中最典型的應用在 orm 上。

python 呼叫關係型資料庫基本上都是通過 database api 來實現的,查詢資料依賴於 sql,orm 最大方便之一就是能生成查詢所用的 sql。

非關係型資料庫中有的 query 語句也支援條件查詢,比如 aws 的 dynamodb。那麼如何通過 orm 來生成 query 語句也是一直重要的地方。

在 peewee 文件的 query operators 中可以看到這個 orm 支援常用的操作符來表示欄位和字段之間的關係。

文件中還用通過函式來表達關係,他們實質上是一樣的,但是這個不在討論範圍之類

# find the user whose username is "charlie".

user.select().where(user.username == 'charlie')

# find the users whose username is in [charlie, huey, mickey]

user.select().where(user.username << ['charlie', 'huey', 'mickey'])

複製**

從上面**中可以看出用==來表示相等,用<<表示 in。

中心思想非常簡單:儲存還原操作符與引數

python 所支援的操作符都可以通過重寫魔法方法來重新實現邏輯,所以在魔法方法中已經可以拿到操作符和引數。

一元操作符和二元操作符都是如此。

所以,最開始那個問題可以分為兩個步驟來完成。

第一步,儲存操作符和引數,可以採用乙個類重寫相關操作符完成。

class

expression:

def__eq__

(self, other):

return operator('==', other)

def__lt__

(self, other):

return operator('<', other)

def__le__

(self, other):

return operator('<=', other)

def__gt__

(self, other):

return operator('>', other)

def__ge__

(self, other):

return operator('>=', other)

複製**

第二步,還原操作符和引數。在 operator 類中完成從操作符轉化為函式的過程。

import operator

class

operator:

def__init__

(self, operator_, rhs):

self._operator = operator_

self._rhs = rhs

self._operator_map =

@property

defvalue

(self):

return self._rhs

@property

defoperator

(self):

return self._operator_map[self._operator]

複製**

乙個 operator 的例項就是乙個運算表示式,可以自己定義操作符和函式的關係,來完成一些特殊的操作。

所以,有了 expression 和 operator,就能很優雅地解出最開始問題的答案

def

pick_range

(data, left_exp, right_exp):

lvalue = left_exp.value

rvalue = right_exp.value

loperator = left_exp.operator

roperator = right_exp.operator

return [item for item in data if loperator(item, lvalue) and roperator(item, rvalue)]

複製**

最後來幾個測試用例

>>> exp = expression()

>>> data = [1, 3, 4, 5, 6, 8, 9]

>>> pick_range(data, 1

< exp, exp < 6)

[3, 4, 5]

>>> pick_range(data, 1

<= exp, exp < 6)

[1, 3, 4, 5]

>>> pick_range(data, 1

< exp, exp <= 6)

[3, 4, 5, 6]

>>> pick_range(data, 1

<= exp, exp <= 6)

[1, 3, 4, 5, 6]

>>>

複製**

關於傳遞運算表示式,知道的人會覺得簡單,不知道的人一時間摸不著頭腦。

python 強大神秘,簡約的邏輯中總是有複雜的背後支援,深入 python 才能明白 python 之美。

Python 變數,運算表示式

變數 變數不需要先定義,可以直接複製使用 變數可重複儲存不同的資料型別 可同時為多個變數複製,用逗號隔開 a,b a b 不支援自增自減 變數引用計數 相同資料的賦值,會共享同一片空間位址,並非占用乙個新的位址單元,節約記憶體。使用sys模組下的getrefcount 函式檢視變數引用計數 impo...

運算表示式求值模板

表示式計算 使用方法 輸入合法的表示式,加減乘除,可以帶括號,用空格分開數字和符號,1為結束標誌,比如 2 5 3 1 注意 這是用來算具體答案的,不是轉化成字尾表示式輸出的,當然,思想是遞迴建立表示式樹,然後後序遍歷得逆波蘭式,然後用棧計算結果 模板 include include include...

python 基礎系列03 運算表示式

第二節,運算表示式 引入sys庫 import sys if name main python3結果向浮點數接近 a 1.0 1 print a print 6 3 2.0 取整運算,向下取整,下面的結果都是3 print 6 2 print 7 2 向上取整或者保持精度 print round 7...