如何将常量变量传递给函数
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'])
当前优化器将 list
和 tuple
文字转换为 tuple
常量,将 set
和 frozenset
文字转换为 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
在以下场景中哪个设计更好,为什么?
甲:
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'])
当前优化器将 list
和 tuple
文字转换为 tuple
常量,将 set
和 frozenset
文字转换为 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