Python检查列表项是否包含任何其他列表项

2024-10-01 17:40:16 发布

您现在位置:Python中文网/ 问答频道 /正文

如果列表元素包含“非法”字符,我想删除该元素时会遇到这个问题。合法字符在多个列表中指定。它们是这样形成的,其中alpha代表字母表(a-z+a-z),digit代表数字(0-9),punct代表标点符号(某种程度上)。在

alpha = list(string.ascii_letters)
digit = list(string.digits)
punct = list(string.punctuation)

这样我就可以指定一个非法字符,如果它没有出现在这些列表中。在

之后,我有一个包含元素的列表:

^{pr2}$

我想过滤掉包含非法字符的元素。所以这就是我想要得到的结果(不需要订购):

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和p

我也试过:

for InItem in Input:
    if not any(AlItem in InItem for AlItem in alpha+digit+punct):

但在那之后,我就不知道如何删除元素了。 哦,还有一个小提示,为了让它变得更加困难,如果它稍微快一点就好了,因为它需要做数百万次。但它必须首先发挥作用。在


Tags: inalpha元素列表forinputstring代表
3条回答

如果所有字符都符合您的条件,您可以使用列表理解并检查all

>>> [element for element in Input if all(c in alpha + digit + punct for c in element)]
['Amuu2', 'Q1BFt', 'mgF)`', 'Y9^^M', 'W0PD7']

你的代码

正如您所提到的,只要any字符是正确的,就立即追加单词。您需要检查它们是否正确:

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']

您还可以检查是否没有一个字符不正确:

^{pr2}$

但是它的可读性要差得多。在

为了提高效率,您不应该在每次迭代期间用alpha+digit+punct连接列表。你应该在任何循环之前做一次彻底的。从这些列表中创建一个集合也是一个好主意,因为当有许多允许的字符时,char in set比{}快得多。在

最后,可以使用列表理解来避免for循环。如果你做了这些,你会得到@timgeb's solution:)

可替代regex

您可以从列表中创建regex模式并查看匹配的单词:

# 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需要更多的时间,但是过滤可能会更快。在

定义一组合法字符。然后应用列表理解。在

>>> 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']

相关问题 更多 >

    热门问题