我想为列表的一部分分配一个值.除了以下之一之外,还有更好的解决方案吗?
也许性能最好,但有些丑陋:
>>> l=[0,1,2,3,4,5]
>>> for i in range(2,len(l)): l[i] = None
>>> l
[0, 1, None, None, None, None]
Run Code Online (Sandbox Code Playgroud)
简洁(但我不知道Python是否认识到不需要重新排列列表元素):
>>> l=[0,1,2,3,4,5]
>>> l[2:] = [None]*(len(l)-2)
>>> l
[0, 1, None, None, None, None]
Run Code Online (Sandbox Code Playgroud)
同样的警告如上:
>>> l=[0,1,2,3,4,5]
>>> l[2:] = [None for _ in range(len(l)-2)]
>>> l
[0, 1, None, None, None, None]
Run Code Online (Sandbox Code Playgroud)
不确定是否使用库来执行这样一个简单的任务是明智的:
>>> import itertools
>>> l=[0,1,2,3,4,5]
>>> l[2:] = itertools.repeat(None,len(l)-2)
>>> l
[0, 1, None, None, None, None]
Run Code Online (Sandbox Code Playgroud)
我看到切片的赋值(对于for循环)的问题是Python可能会尝试准备"l"长度的变化.毕竟,通过插入更短/更长的切片来更改列表涉及复制列表AFAIK的所有元素(即所有引用).如果Python也在我的情况下这样做(虽然没有必要),操作变为O(n)而不是O(1)(假设我只是总是改变一些元素).
时间安排:
python -mtimeit "l=[0,1,2,3,4,5]" "for i in range(2,len(l)):" " l[i] = None"
1000000 loops, best of 3: 0.669 usec per loop
python -mtimeit "l=[0,1,2,3,4,5]" "l[2:] = [None]*(len(l)-2)"
1000000 loops, best of 3: 0.419 usec per loop
python -mtimeit "l=[0,1,2,3,4,5]" "l[2:] = [None for _ in range(len(l)-2)]"
1000000 loops, best of 3: 0.655 usec per loop
python -mtimeit "l=[0,1,2,3,4,5]" "l[2:] = itertools.repeat(None,len(l)-2)"
1000000 loops, best of 3: 0.997 usec per loop
Run Code Online (Sandbox Code Playgroud)
看起来l[2:] = [None]*(len(l)-2)是您提供的最佳选项(对于您正在处理的范围).
注意:
请记住,结果将根据Python版本,操作系统,其他当前正在运行的程序而变化,最重要的是 - 列表的大小和要替换的切片的大小.对于较大的范围,可能最后一个选项(使用itertools.repeat)将是最有效的,既易于阅读(pythonic)又高效(性能).
您的所有解决方案都是Pythonic,同样具有可读性.如果您真的关心性能并认为在这种情况下它很重要,请使用该timeit模块对它们进行基准测试.
话虽如此,我希望第一个解决方案几乎肯定不是最高效的解决方案,因为它迭代Python中的列表元素.此外,Python不会优化远离列表在分配右侧创建的列表,但列表创建速度非常快,并且在大多数情况下,一个小的临时列表根本不会影响执行.就个人而言,对于一个简短的列表,我会选择你的第二个解决方案,并且我会选择更长的列表itertools.repeat().
请注意,itertools它并不真正算作"库",它带有Python,并且经常被使用,它本质上是语言的一部分.
我认为 Python 中没有直接开箱即用的功能来做到这一点。我喜欢你的第二种方法,但请记住,空间和时间之间需要权衡。这是 @user4815162342 推荐的一本非常好的读物:Python 模式 - 优化轶事。
无论如何,如果这是您最终将在代码中执行的操作,我认为最好的选择是将其包装在辅助函数中:
def setvalues(lst, index=0, value=None):
for i in range(index, len(lst)):
lst[i] = value
>>>l=[1,2,3,4,5]
>>>setvalues(l,index=2)
>>>l
>>>[1, 2, None, None, None]
Run Code Online (Sandbox Code Playgroud)
这有一些优点:
恕我直言,这个操作没有直接的 Python 未来,这是我能想象到的最好的解决方法。
希望这可以帮助!
| 归档时间: |
|
| 查看次数: |
626 次 |
| 最近记录: |