忽略字符串中的大小写,标点符号和空格

时间:2010-01-30 19:41:37

标签: python filter state slice

忽略字符串中的大小写,标点符号和空格的最有效方法是什么?这些字符串应该被分成单词而不是字符,应该忽略前面提到的比较细节,这些字串的切片应该尽可能高效,并考虑到速度。

我打算对以下代码使用大小写和标点符号不敏感字符串,但在看到评估class Slice: def __eq__(self, other): return self.root == other.root需要多长时间后,我决定使用data = tuple(string.split())。在下面的代码中已经表达的计算成本高昂的算法中,使用对大小写,标点符号和间距不敏感且对单词而不是字符起作用的字符串太昂贵了。

class Slice:

    def __init__(self, data, offset, length):
        self.prefix = data[:offset]
        self.root = data[offset:offset+length]
        self.suffix = data[offset+length:]

    def __eq__(self, other):
        return self.root == other.root

    def __len__(self):
        return len(self.root)

################################################################################

class Match:

    def __init__(self, data, key, prefix_tree, suffix_tree):
        self.data = data
        self.key = key
        self.prefix_tree = prefix_tree
        self.suffix_tree = suffix_tree
        self.__value = len(key) + prefix_tree.value() + suffix_tree.value()

    def value(self):
        return self.__value

################################################################################

class Tree(tuple):

    def __new__(cls, nodes):
        tree = super().__new__(cls, nodes)
        tree.__value = max(map(Match.value, tree)) if tree else 0
        return tree

    def value(self):
        return self.__value

    def find(self, value):
        for index, match in enumerate(self):
            if match.value() == value:
                return index
        raise ValueError()

################################################################################

def search(data, key):
    length = 0
    nodes = []
    for d_block in shrink(data, len(key)):
        block_len = len(d_block)
        if length > block_len:
            return Tree(nodes)
        for k_block in slide(key, block_len):
            if d_block == k_block:
                length = block_len
                prefix_tree = search(d_block.prefix, k_block.prefix)
                suffix_tree = search(d_block.suffix, k_block.suffix)
                match = Match(d_block, k_block, prefix_tree, suffix_tree)
                nodes.append(match)
    return Tree(nodes)

def shrink(data, max_len):
    for length in range(min(len(data), max_len), 0, -1):
        for block in slide(data, length):
            yield block

def slide(data, length):
    for offset in range(len(data) - length + 1):
        yield Slice(data, offset, length)

################################################################################

def build_tree(nodes):
    match = nodes[nodes.find(nodes.value())]
    node = match.key
    if match.prefix_tree:
        node.prefix = build_tree(match.prefix_tree)
    if match.suffix_tree:
        node.suffix = build_tree(match.suffix_tree)
    return node

def flatten_tree(node):
    array = [0]
    _flatten(node, array)
    return tuple(array)

def _flatten(node, array):
    if isinstance(node.prefix, Slice):
        _flatten(node.prefix, array)
    else:
        array.append(node.prefix)
    array[0] += 1
    array.append((array[0], node.root))
    if isinstance(node.suffix, Slice):
        _flatten(node.suffix, array)
    else:
        array.append(node.suffix)

2 个答案:

答案 0 :(得分:2)

如果你想在一个String实例上迭代迭代它的self.__string,正如你的__iter__方法所指出的那样,长度的唯一合理选择也是返回__string的长度 - - 如果len(x)sum(1 for _ in x)导致不同的值,那么真正是特殊的。

我不得不承认我不明白这门课的目的(特别是为什么你做出了旧式的糟糕选择,为什么你用这种扭曲的方式来构建__simple)但无论如何,内部一致性很重要。因此,要么更改__iter__,要么使__len__在逻辑上与之兼容。

你的切片逻辑也完全逃脱了我 - 你为什么要以一种可能与你从切片__simple重建它的方式不同的方式构建切片的__string?例如,如果self.__string是'?Boh!'因此self.__simple是'boh',为什么你希望 self[1:-1]拥有__string'Boh',但__simple为' o',与你从片中重新计算得到的__simple不相容,不同和不一致......?

我想这与Q关于长度没有密切关系,但我只是对你正在制作的这些非常奇特的设计选择感到好奇......

答案 1 :(得分:2)

“修复此问题的最佳方法是什么?”

最好也是唯一的方法是定义这个对象“的意思”以及这个对象的长度“意味着”。

该对象似乎是一个单词列表。而已。这似乎是_string中的价值。

_simple中字词的无法访问的过滤子集外,还不清楚_string是什么。

那么长度是多少?单词的长度或过滤子集中单词的长度?

只有您可以定义此类的含义。然后,含义将决定如何实施__len__。在定义含义之前,无法确定应该如何实现任何内容。