如何将常量变量传递给函数

How to pass a constant variable to a function

在以下场景中哪个设计更好,为什么?

甲:

stop_words = ['com1', 'com2'] 
    
def clean_text(text_tokens, stop_words):
    return [token for token in text_tokens if token not in stop_words]

clean_text(['hello', 'world', 'com1', 'com2'], stop_words)

乙:

def clean_text(text_tokens):
    stop_words = ['com1', 'com2']
    return [token for token in text_tokens if token not in stop_words]

clean_text(['hello', 'world', 'com1', 'com2'])

C:

STOP_WORDS = ['com1', 'com2'] 
    
def clean_text(text_tokens):
    return [token for token in text_tokens if token not in STOP_WORDS]

clean_text(['hello', 'world', 'com1', 'com2'])

根据@MisterMiyagi 的回答添加了 C 版本。

注 1:在此上下文中,stop_words 是固定不变的。

注意 2:stop_words 可以是一个小列表,也可以是一个非常大的列表。

如果您想在每次调用函数时将不同的列表作为 stop_words 作为参数传递,方案 A 更好,而方案 B 只针对 ['com1','com2'] 进行测试,这意味着您只需更改当您编辑函数本身时此列表。

总结:场景A比较好,测试不同的列表,在函数中作为参数传递。

更喜欢在全局范围内创建常量。全局作用域计算一次,而function-local作用域在每次函数调用时计算

对于非常大的搜索,更喜欢使用 set 因为它的 O(1) 查找,而不是 list O(n) 查找。旨在作为 constants should be named with ALL_CAPS_NAMES 的值。函数应该直接引用常量 iff​​ 它们不应该被替换。

STOP_WORDS = {'com1', 'com2'}  # constant set of words
    
def clean_text(text_tokens):
    return [token for token in text_tokens if token not in STOP_WORDS]
    #                             directly access constant ^

clean_text(['hello', 'world', 'com1', 'com2'])

对于小常量,以文字形式提供它们可能更有利。甚至 CPython 也能够将内联文字优化为实际常量。

def clean_text(text_tokens):
    return [
        token
        for token in text_tokens
        if token not in {'com1', 'com2'}
        #               ^ compiled as LOAD_CONST (frozenset({'com2', 'com1'}))
    ]

clean_text(['hello', 'world', 'com1', 'com2'])

当前优化器将 listtuple 文字转换为 tuple 常量,将 setfrozenset 文字转换为 frozenset 常量

中间立场:使用参数的默认值。

def clean_text(text_tokens, stop_words={'com1', 'com2'}):
    return [token for token in text_tokens if token not in stop_words]

clean_text(['hello', 'world', 'com1', 'com2'])

现在常量{'com1', 'com2'}只创建一次(定义函数时);它不会污染全局范围;如果您最终想要,您可以选择在调用 clean_text.

时传递不同的 stop_words