簡體   English   中英

Python檢查列表項是否包含任何其他列表項

[英]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 listchar 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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM