Tokenize函数不能按预期工作 - Python

时间:2017-09-22 19:50:08

标签: python python-3.x debugging optimization code-organization

这些是说明:

编写一个函数tokenize(input_string),它接受​​一个包含表达式的字符串并返回一个标记列表。这种小语言中的标记将由空格分隔,因此,只要输入字符串中有空格(或一行中有多个空格),我们就要分开它。

您不应该使用内置的字符串操作拆分,而应该使用我们目前开发的工具来构建您的代码。

完成所有操作后,例如,在此字符串上运行tokenizer: tokenize("2 2 + 3 4 / .5 0.2 3.2 + - COS")

应该返回: ['2', '2', '+', '3', '4', '/', '.5', '0.2', '3.2', '+', '-', 'COS']

这是我的代码:

def tokenize(input_string):
    tokens = []
    token = ""
    for char in input_string:
        if char == " " and input_string[-1] != char and token != "":
            tokens.append(token)
            token = ""
        elif input_string[-1] == char:
            tokens.append(token + char)
        elif char != " ":
            token += char
    return tokens

我的代码与给定的示例和类似的参数一起正常工作,但是当我运行类似于: tokenize("pi load store load")

我得到: ['pi', 'load', 'loa', 'store', 'load'] 什么是虫子?试图在功能的各个部分用print语句找到它无济于事。此外,任何关于如何更好地组织if语句的建议将不胜感激。在此先感谢您的帮助。

3 个答案:

答案 0 :(得分:0)

我认为你的缺陷在Traceback (most recent call last): File "C:/Users/marti_000/BabyProjects/webApp/run.py", line 5, in <module> app.run() File "C:\Users\marti_000\AppData\Local\Programs\Python\Python36- 32\lib\site-packages\eve\flaskapp.py", line 201, in run super(Eve, self).run(host, port, debug, **options) File "C:\Users\marti_000\AppData\Local\Programs\Python\Python36- 32\lib\site-packages\flask\app.py", line 841, in run run_simple(host, port, self, **options) File "C:\Users\marti_000\AppData\Local\Programs\Python\Python36- 32\lib\site-packages\werkzeug\serving.py", line 708, in run_simple inner() File "C:\Users\marti_000\AppData\Local\Programs\Python\Python36- 32\lib\site-packages\werkzeug\serving.py", line 670, in inner fd=fd) File "C:\Users\marti_000\AppData\Local\Programs\Python\Python36- 32\lib\site-packages\werkzeug\serving.py", line 564, in make_server passthrough_errors, ssl_context, fd=fd) File "C:\Users\marti_000\AppData\Local\Programs\Python\Python36- 32\lib\site-packages\werkzeug\serving.py", line 476, in __init__ HTTPServer.__init__(self, (host, int(port)), handler) File "C:\Users\marti_000\AppData\Local\Programs\Python\Python36- 32\lib\socketserver.py", line 453, in __init__ self.server_bind() File "C:\Users\marti_000\AppData\Local\Programs\Python\Python36- 32\lib\http\server.py", line 138, in server_bind self.server_name = socket.getfqdn(host) File "C:\Users\marti_000\AppData\Local\Programs\Python\Python36- 32\lib\socket.py", line 673, in getfqdn hostname, aliases, ipaddrs = gethostbyaddr(name) UnicodeDecodeError: 'utf-8' codec can't decode byte 0x9e in position 1: invalid start byte 行。

如果我正确理解你,你试图使用这个elif input_string[-1] == char:案例检查你是否在字符串的末尾,如果你是,那么将字符串中的最后一个标记添加到你的令牌列表。

但是,如果你的字符串中的最后一个字符出现不止一次,那么每次都会出现这种情况;这就是您列表中同时包含elif'loa'的原因。

我的建议是删除当前字符的所有检查,与字符串中的最后一个字符相同,然后添加

'load'
在你的for循环之后

答案 1 :(得分:0)

要添加Izaak Weiss的答案,请简化您的检查逻辑,这可能是一个解决方案:

def tokenize(input_string):
    tokens = []
    token = ''
    for char in input_string:
        if char == ' ': # Possible token termination
            if token != '':
                tokens.append(token)
                token = ''
        else:
            token += char

    # Last token
    if token != '':
        tokens.append(token) 

    return tokens

答案 2 :(得分:0)

以下是两种方法:

当然还有其他一些(例如那些使用递归,甚至是正则表达式),但它们可能太先进了。

def tokenize_plain(input_string):
    tokens = list()
    current_token = ""
    for char in input_string:
        if char == " ":
            if current_token:
                tokens.append(current_token)
                current_token = ""
        else:
            current_token += char
    if current_token:
        tokens.append(current_token)
    return tokens


def tokenize_find(input_string):
    tokens = list()
    start = 0
    end = input_string.find(" ", start)
    while end != -1:
        if end == start:
            start += 1
        else:
            tokens.append(input_string[start: end])
            start = end
        end = input_string.find(" ", start)
    end = input_string.rfind(" ", start)
    if end == -1:
        tokens.append(input_string[start:])
    else:
        tokens.append(input_string[start: end])
    return tokens


if __name__ == "__main__":
    for tokenize in [tokenize_plain, tokenize_find]:
        for text in ["pi load store load", "2 2 + 3 4 / .5 0.2 3.2 + - COS"]:
            print("{}('{}') = {}".format(tokenize.__name__, text, tokenize(text)))

<强>输出

c:\Work\Dev\StackOverflow\q46372240>c:\Work\Dev\VEnvs\py35x64_test\Scripts\python.exe a.py
tokenize_plain('pi load store load') = ['pi', 'load', 'store', 'load']
tokenize_plain('2 2 + 3 4 / .5 0.2 3.2 + - COS') = ['2', '2', '+', '3', '4', '/', '.5', '0.2', '3.2', '+', '-', 'COS']
tokenize_find('pi load store load') = ['pi', 'load', 'store', 'load']
tokenize_find('2 2 + 3 4 / .5 0.2 3.2 + - COS') = ['2', '2', '+', '3', '4', '/', '.5', '0.2', '3.2', '+', '-', 'COS']