【问题标题】:For loop is stoppingFor循环正在停止
【发布时间】:2021-09-23 17:08:00
【问题描述】:

我正在尝试创建一个返回单词相似度的函数,但循环在仅处理第一个参数后停止!例如,如果我执行example.py hello there,程序会返回:

hello is close to: 

held, heel, helpt, hele, Hallo, het, helaas, half, helden, heb, veel, Meld, zelf, heeft, beeld, alle, wel, Rel, Geld, cel, geld, Alle, hoezo, 
 there is close to:

这是我的代码:

def create_data():
    data =defaultdict(int)
    value = 0
    for line in sys.stdin:
        [ident, user, text, terms] = line.rstrip().split('\t')
        for word in terms.split():
            data[word] = value

    return data

def find_closest(word):

    data = create_data()
    data_with_distance= defaultdict(int)
    for key in data:
        distance = lev_dist(word, key)
        data_with_distance[key] = distance
    return {k: v for k, v in sorted(data_with_distance.items(), key=lambda item: item[1])}


def main():
    if len(sys.argv) > 1:

        for w in sys.argv[1:]:
            print("\n",w, "is close to:\n")
            closest = find_closest(w)
            closest_words = [k for k, v in closest.items() if v < 4]
            #minimal_distance = list(closest.values())[0]
            for close in closest_words:
                print(close, end=", ")

    else:
        sys.stderr.write("no argument\n")

if __name__ == '__main__':
    main()

【问题讨论】:

  • create_data 返回什么?
  • 请提供minimal reproducible example。您提供的代码无法复制。
  • 默认字典,以文本中的所有单词为键,0为值。
  • 是的,这就是问题所在。它是非幂等的,因为它会在您第一次运行它时消耗整个 stdin 流。调用一次,缓存结果,并将其传递给find_closest
  • create_data 产生一个非空序列一次

标签: python function for-loop


【解决方案1】:

如果要复用create_data的结果,需要缓存:

def find_closest(word, data):  # take data as param here
    data_with_distance= defaultdict(int)
    for key in data:
        distance = lev_dist(word, key)
        data_with_distance[key] = distance
    return {k: v for k, v in sorted(data_with_distance.items(), key=lambda item: item[1])}


def main():
    data = create_data()  # load data from stdin ONCE

    if len(sys.argv) > 1:

        for w in sys.argv[1:]:
            print("\n",w, "is close to:\n")
            closest = find_closest(w, data)  # pass data as param here
            closest_words = [k for k, v in closest.items() if v < 4]
            #minimal_distance = list(closest.values())[0]
            for close in closest_words:
                print(close, end=", ")

另一种选择是在create_data 上粘贴一个缓存装饰器:

from functools import cache

@cache
def create_data():
    data = defaultdict(int)
    value = 0
    for line in sys.stdin:
        [ident, user, text, terms] = line.rstrip().split('\t')
        for word in terms.split():
            data[word] = value
    return data

这“修复”了函数,使其缓存第一次运行时的结果,并在后续调用中返回相同的结果,而不是实际执行函数。

在接受参数的函数中,缓存将基于参数进行;因为这个函数没有参数,它只会缓存一个返回值。如果该函数有 desirable 副作用,您不希望像这样缓存它,但在这种情况下,副作用是 undesirable 所以贴上@cache 是一个非常简单的解决方案。

【讨论】:

    猜你喜欢
    • 2022-01-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多