![](/img/trans.png)
[英]Is there a way in Robot Framework/Python to filter a list of dictionaries using regular expressions?
[英]Good and pythonic way to filter list of dictionaries with regular expressions
所以假設我有一個這樣的列表/元組。
dic = ({name: 'Kan',number: '2ABC345', year: '2000'},
{name: 'Jhon',number: '2TTC345', year: '2001'},
{name: 'Louise',number: '2ABC366', year: '2001'},
{name: 'Kevin',number: '2ABY000', year: '2002'})
如何在此列表中使用過濾器和正則表達式? 我在想這樣的事情,但我似乎無法更正代碼。
def func(dic, expression, keysection):
r = re.compile(dic)
x = list(filter(lambda x: r.findall(rexpression) in x[keysection], dic))
print(x)
所以假設我想要 2000 年我會做這樣的事情,
func(dic, 2000, 'year')
>>> [{name: 'Kan',number: '2ABC345', year: 2000}]
或名稱的第一個字母是 ak,
func(dic, '^K', 'name')
>>> [ {name: 'Kan',number: '2ABC345', year: 2000}, {name: 'Kevin',number: '2ABY000', year: 2002}]
或查看數字是否以 2 開頭並有 7 個數字,
func(dic, '2\d{7}', 'number')
>>> [ {name: 'Kan',number: '2ABC345', year: 2000}, {name: 'Jhon',number: '2TTC345', year: 2001},{name: 'Louise',number: '2ABC366', year: 2001}, {name: 'Kevin',number: '2ABY000', year: 2002} ]
問題是,我是正則表達式的新手,我不確定上面的代碼是否正確,以及使用正則表達式過濾器的最佳和最 Python 的方式是什么。
我不會嘗試讓 function 承擔所有這些責任。 這將使測試變得異常困難。 相反,我會為每種情況使用最簡單的列表推導:
import re
dic = (
{"name": "Kan", "number": "2ABC345", "year": 2000},
{"name": "Jhon", "number": "2TTC345", "year": 2001},
{"name": "Louise", "number": "2ABC366", "year": 2001},
{"name": "Kevin", "number": "2ABY000", "year": 2002},
)
# So let's say I want the year 2000
year_2000 = [d for d in dic if d["year"] == 2000]
# or the first letter in name be a k
name_k = [d for d in dic if d["name"].startswith("K")]
# or to see if the number starts with 2 and has 7 numbers
starts_2_digits_7 = [d for d in dic if re.match(r"^2\d{6}$", d["number"])]
您不需要為它創建 function。 正則表達式必須是可讀的。 Lambda 完成這項工作。
print(list(filter(lambda x: x['year'] == 2000, dic)))
# Output:
[{'name': 'Kan', 'number': '2ABC345', 'year': 2000}]
print(list(filter(lambda x: x['name'][0] == 'K', dic)))
# Output:
[{'name': 'Kan', 'number': '2ABC345', 'year': 2000},
{'name': 'Kevin', 'number': '2ABY000', 'year': 2002}]
print(list(filter(lambda x: x['number'][0] == '2' and len(x['number']) == 7, dic)))
# Output:
[{'name': 'Kan', 'number': '2ABC345', 'year': 2000},
{'name': 'Jhon', 'number': '2TTC345', 'year': 2001},
{'name': 'Louise', 'number': '2ABC366', 'year': 2001},
{'name': 'Kevin', 'number': '2ABY000', 'year': 2002}]
但我真的建議為此使用 pandas。
讓我們從正則表達式對字符串進行操作的說明開始。 因此,您最好更正您的dic ,以便每個字典都包含字符串(最初年份是一個數字)。
您應該做的第一個更正是re.compile(dic)
是錯誤的。 您可以編譯模式,而不是字典。
而且由於您只執行一次模式,因此無需提前編譯它。 僅使用模式參數(字符串)時會更簡單。
您的 function 可以是:
def func(dic, pat, key):
return list(filter(lambda x: re.search(pat, x[key]), dic))
當您只想打印找到的內容時,function 返回結果就足夠了,當您調用 function 時,結果將被打印出來。
試試func(dic, '2000', 'year')
和func(dic, '^K', 'name')
。 它應該打印你想要的。
但是嘗試運行func(dic, '2\d{7}', 'number')
將返回[] (一個空列表),因為您的數據樣本中沒有數字包含2后跟 7 位數字。
但是您可以例如運行func(dic, '2A[AZ]{2}', 'number')
,即查找包含以下數字的字典:
這次你會得到:
[{'name': 'Kan', 'number': '2ABC345', 'year': '2000'},
{'name': 'Louise', 'number': '2ABC366', 'year': '2001'},
{'name': 'Kevin', 'number': '2ABY000', 'year': '2002'}]
如果您的字典中有一些字符串以外的元素,您可以將它們轉換為 function 中的字符串。 將您的 function 更改為:
def func(dic, pat, key):
return list(filter(lambda x: re.search(pat, str(x[key])), dic))
它也適用於源字典中的非字符串元素。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.