Cyo*_*yon 3 python if-statement list-comprehension list
我正在做一些字符串解析,如果字符是字母则要返回1,如果字符是数字则返回2,如果字符是其他字符则返回.
通常我会使用for循环并像这样附加到它
string = 'hello123...'
values = []
for char in string:
if char.isalpha():
values.append(1)
elif char.isdigit():
values.append(2)
Run Code Online (Sandbox Code Playgroud)
返回
[1, 1, 1, 1, 1, 2, 2, 2]
Run Code Online (Sandbox Code Playgroud)
正如所料.根据/sf/answers/2117182581/使用列表推导可以快得多.所以我尝试过:
values = [1 if char.isalpha else 2 if char.isdigit for char in string]
Run Code Online (Sandbox Code Playgroud)
但是,这给了我一个语法错误,因为'else'是预期的.
File "C:/Users/test3.py", line 12
values = [1 if char.isalpha else 2 if char.isdigit for char in string]
^
SyntaxError: invalid syntax
Run Code Online (Sandbox Code Playgroud)
如果角色不是字母数字,我希望它不添加任何内容.我的代码出了什么问题?
我将不得不执行这个功能数十亿次,所以如果有更好的方法可以做到这一点,那么效率的提高是值得欢迎的.
如果您根本不想考虑特定元素,则应该在理解结束时将该条件作为保护包括在内.
[1 if char.isalpha() else 2 for char in string if char.isdigit() or char.isalpha()]
Run Code Online (Sandbox Code Playgroud)
所述if char.isdigit() or char.isalpha()在端部消除了不能满足那些谓词的任何元件.
话虽这么说,为了便于阅读,我建议至少将翻译部分(以及可能的条件)分解为单独的函数.这个单行,虽然看起来很聪明,但它并不十分可读.
其他答案很好地解释了如何更改列表理解以正确处理非字母数字情况。相反,我想解决列表理解总是比传统循环快得多的假设。
这通常是正确的,但很多时候您可以修改循环来弥补大部分或全部丢失的部分。append特别是,在列表中查找方法相对较慢,因为它涉及在字典中查找某些内容并创建绑定方法对象。您可以更改代码以在循环之前执行一次查找,并且您的代码最终可能比任何其他版本更快:
values = []
values_append = values.append # cache this method lookup
for char in string:
if char.isalpha():
values_append(1) # used cached method here
elif char.isdigit():
values_append(2) # and here
Run Code Online (Sandbox Code Playgroud)
以下是一些测试时间,使用一百万个字符串:
import random, timeit
big_str = "".join(random.choice(['a', '1', '~']) for _ in range(1000000))
def loop_cyon(string):
values = []
for char in string:
if char.isalpha():
values.append(1)
elif char.isdigit():
values.append(2)
return values
def comp_silvio_mayolo(string):
return [1 if char.isalpha() else 2 for char in string if char.isdigit() or char.isalpha()]
def comp_amadan1(string):
return [1 if char.isalpha() else 2 for char in string if char.isalnum()]
def comp_amadan2(string):
return list(filter(None, (1 if char.isalpha() else 2 if char.isalnum() else None for char in string)))
def loop_blckknght(string):
values = []
values_append = values.append
for char in string:
if char.isalpha():
values_append(1)
elif char.isdigit():
values_append(2)
return values
for func in [loop_cyon, comp_silvio_mayolo, comp_amadan1, comp_amadan2, loop_blckknght]:
print(func.__name__)
timeit.timeit(lambda: func(big_str), number=10)
Run Code Online (Sandbox Code Playgroud)
我的系统上的输出(Windows 10 64x,Python 3.6):
loop_cyon 2.5896435911574827
comp_silvio_mayolo 2.6970998627145946
comp_amadan1 2.177768147485949
comp_amadan2 2.676028711925028
loop_blckknght 2.244682003625485
Run Code Online (Sandbox Code Playgroud)
所以看起来最好的列表理解仍然比我的循环代码快一点,但也快不了多少。我当然会说,在这种情况下,显式循环更加清晰,并且这种清晰性可能比性能差异更重要。
| 归档时间: |
|
| 查看次数: |
406 次 |
| 最近记录: |