[英]Python Check if list item does (not) contain any of other list items
我有這個問題,我想刪除列表元素,如果它包含'非法'字符。 合法字符在多個列表中指定。 它們是這樣形成的,其中alpha
代表字母(az + AZ), digit
代表數字(0-9), punct
代表標點符號(排序)。
alpha = list(string.ascii_letters)
digit = list(string.digits)
punct = list(string.punctuation)
這樣我可以將某些內容指定為非法字符,如果它沒有出現在其中一個列表中。
之后我有一個包含元素的列表:
Input = ["Amuu2", "Q1BFt", "dUM€n", "o°8o1G", "mgF)`", "ZR°p", "Y9^^M", "W0PD7"]
我想過濾掉包含非法字符的元素。 所以這是我想得到的結果(不需要訂購):
var = ["Amuu2", "Q1BFt", "mgF)`", "Y9^^M", "W0PD7"]
編輯:
我試過(以及它的所有變體):
for InItem in Input:
if any(AlItem in InItem for AlItem in alpha+digit+punct):
FilInput.append(InItem)
其中僅使用過濾后的元素創建新列表,但問題是當包含至少一個合法字符時添加元素。 例如:添加了"ZR°p"
,因為它包含Z,R和a p。
我也嘗試過:
for InItem in Input:
if not any(AlItem in InItem for AlItem in alpha+digit+punct):
但在那之后,我無法弄清楚如何刪除元素。 哦,還有一點小小的提示,為了讓它變得更加困難,如果它有點快,那將會很好,因為它需要做數百萬次。 但它需要首先工作。
定義一組合法字符。 然后應用列表理解。
>>> allowed = set(string.ascii_letters + string.digits + string.punctuation)
>>> inp = ["Amuu2", "Q1BFt", "dUM€n", "o°8o1G", "mgF)`", "ZR°p", "Y9^^M", "W0PD7"]
>>> [x for x in inp if all(c in allowed for c in x)]
['Amuu2', 'Q1BFt', 'mgF)`', 'Y9^^M', 'W0PD7']
您可以使用列表理解與檢查all
,如果所有字符匹配您的標准:
>>> [element for element in Input if all(c in alpha + digit + punct for c in element)]
['Amuu2', 'Q1BFt', 'mgF)`', 'Y9^^M', 'W0PD7']
正如您所提到的,只要any
字符是正確的,您就會附加單詞。 你需要檢查它們是否all
正確:
filtered_words = []
for word in words:
if all(char in alpha+digit+punct for char in word):
filtered_words.append(word)
print(filtered_words)
# ['Amuu2', 'Q1BFt', 'mgF)`', 'Y9^^M', 'W0PD7']
您還可以檢查是否有一個不正確的字符:
filtered_words = []
for word in words:
if not any(char not in alpha+digit+punct for char in word):
filtered_words.append(word)
print(filtered_words)
但它的可讀性要低得多。
為了提高效率,您不應該在每次迭代期間使用alpha+digit+punct
連接列表。 你應該在任何循環之前一勞永逸地做到這一點。 創建這些列表的集合也是一個好主意,因為當有許多允許的字符時char in set
中的char in list
比char in list
快得多。
最后,您可以使用列表推導來避免for循環。 如果你做了這一切,你最終會得到@ timgeb的解決方案 :)
您可以從列表中創建正則表達式模式,並查看哪些單詞匹配:
# encoding: utf-8
import string
import re
alpha = list(string.ascii_letters)
digit = list(string.digits)
punct = list(string.punctuation)
words = ["Amuu2", "Q1BFt", "dUM€n", "o°8o1G", "mgF)`", "ZR°p", "Y9^^M", "W0PD7"]
allowed_pattern = re.compile(
'^[' +
''.join(
re.escape(char) for char in (
alpha +
digit +
punct)) +
']+$')
# ^[abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789\!\"\#\$\%\&\'\(\)\*\+\,\-\.\/\:\;\<\=\>\?\@\[\\\]\^_\`\{\|\}\~]+$
print([word for word in words if allowed_pattern.match(word)])
# ['Amuu2', 'Q1BFt', 'mgF)`', 'Y9^^M', 'W0PD7']
你也可以這樣寫:
print(list(filter(allowed_pattern.match, words)))
# ['Amuu2', 'Q1BFt', 'mgF)`', 'Y9^^M', 'W0PD7']
re.compile
可能比簡單地初始化一個set
需要更多的時間,但過濾可能會更快。
對於您的問題,這是一個“非”有效的解決方案,但學習如何循環列表,字符等可能很有趣。
# coding=utf-8
import string
# Aux var
result =[]
new_elem = ""
# lists with legal characters
alpha = list(string.ascii_letters)
digit = list(string.digits)
punct = list(string.punctuation)
# Input strings
Input = ["Amuu2", "Q1BFt", "dUM€n", "o°8o1G", "mgF)`", "ZR°p", "Y9^^M", "W0PD7"]
# Loop all elements of the list and each char of them
for elem in Input:
## check each char
for char in elem:
if char in alpha:
#print 'is ascii'
new_elem += char
elif char in digit:
#print 'is digit'
new_elem += char
elif char in punct:
#print 'is punct'
new_elem += char
else:
new_elem = ""
break
## Add to result list
if new_elem != "":
result.append(new_elem)
new_elem = ""
print result
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.