删除集合中包含特定字符的所有元素

Remove all elements of a set that contain a specific char

我有一组由生成器生成的几千个素数:

primes = set(primegen()) = set([..., 89, 97, 101, 103, ...])

其中一些素数中有一个零。我想摆脱他们。有没有办法一次完成所有这些?

目前我正在删除元素,因为我循环遍历素数,使用正则表达式匹配:

import re
zero = re.compile('.+0.+') 

while primes:
    p = str(primes.pop())
    if zero.match(p):
        continue
    # do other stuff

我认为这是最好的方法,但我很好奇我是否错了。

您可以使用集合理解来过滤现有的素数集合。

primes = {p for p in primes if '0' not in str(p)}

对响应进行总结和计时:

前 100000 个素数。 (使用timeit,每次复制素数集)

根目录

primes = {p for p in primes if '0' not in str(p)}

10 次循环,3 次循环中的最佳:29.6 毫秒 每个循环

麦克

while primes:
    p = str(primes.pop())
    if '0' in p:
        continue
    # do other stuff

10 次循环,3 次循环中的最佳:38.9 毫秒 每个循环

加勒特 R

filter(lambda x: '0' not in str(x), primes)

1000 次循环,3 次循环中的最佳循环:963 微秒 每个循环

Kasramvd

def zero_membership_checker(num):
    while num:
        if num%10 == 0:
            return True
        num = num / 10
    return False

1 个循环,3 个循环中的最佳:6.65 秒 每个循环

你好

import re
zero = re.compile('.+0.+') 

while primes:
    p = str(primes.pop())
    if zero.match(p):
        continue
    # do other stuff

10 次循环,3 次循环中的最佳:69.4 毫秒 每个循环

您不需要将数字转换为字符串并使用正则表达式来匹配其中的零(或者更好的是它使用 in 运算符进行成员资格检查),这是一个昂贵的操作,特别是当您正在处理大型数据集。您可以使用以下函数来检测您的数字中是否有任何零,然后在集合理解中使用它来保留预期的数字:

>>> def zero_membership_checker(num):
...     while num:
...         if num%10 == 0:
...             return True
...         num = num / 10
...     return False
... 
>>> s = set([89, 97, 101, 103])
>>> 
>>> {i for i in s if not zero_membership_checker(i)}
set([89, 97])

免责声明:绝对不知道你想用这个做什么或者为什么这会有用。我只是假设您想从 primes 集合中删除像 101103 这样的数字,因为它们包含一个零数字。

你甚至不需要正则表达式。可以通过简单的列表理解来完成:

# assume that primes is defined
str_primes = map(str, primes)
filtered_str_primes = [p for p in primes if "0" not in p]
filtered_primes = map(int, primes)

可能会更快,你应该测试一下。

我不确定你的集合是否只是一个例子,或者你是否打算使用生成器来生成可能无限的素数列表。在后一种情况下,您可以使用 itertools 延迟定义过滤序列(即,in 只会在您请求时生成下一个元素,而不是消耗整个列表):

from itertools import imap, ifilter
filtered_primes = imap(int,
                       ifilter(lambda p: "0" not in p,
                               imap(str, primes)))

等等,我忘了,这应该会产生相同的结果,但代码更少(为了完整起见,我将保留旧的解决方案):

filteres_primes = (p for p in primes if "0" not in str(p))

filter 也适用于此应用程序:

In [25]: primes = set([83, 89, 97, 101, 103])

In [26]: filter(lambda x: '0' not in str(x), primes)
Out[26]: [89, 83, 97]

这里有一些时间信息,供所有好奇的人使用

In [37]: %timeit filter(lambda x: '0' not in str(x), myList)
10 loops, best of 3: 23.7 ms per loop

In [38]: %timeit {p for p in myList if '0' not in str(p)}
10 loops, best of 3: 22 ms per loop