python - 如何将 Python 列表列表的所有值设置为特定值?

标签 python list

是否可以将 Python 列表列表中的所有值设置为 0 而无需逐个遍历列表和值?

我有一个列表列表 [[0, 2, 4, 5], [0, 2, 4, 5]] 我想将其更改为 [[0 , 0, 0, 0], [0, 0, 0, 0]]。有没有一种方法可以在不循环遍历所有值的情况下实现这一目标,这会导致性能提高吗?因为这段代码将被执行很多次,所以最快的方法是什么?

列表是就地修改还是完全替换也无关紧要。外部列表的长度会很大,而内部列表的长度会很小。

最佳答案

不,没有办法避免循环,因为列表的大小是任意的。您还希望避免以共享的单个嵌套列表结束,因此外部列表的乘法已经结束。

以下是合理有效的并产生合理的结果:

[[0] * len(inner) for inner in outer]

这将为任何长度的 outer 产生正确的结果,即使嵌套列表的长度不同也是如此。

这也是跨不同场景的最快方法,如以下时间试验所示。首先要测试的设置:

>>> from timeit import timeit
>>> import random
>>> short_fixed = [[random.randint(0, 10) for _ in range(5)] for _ in range(10)]
>>> long_fixed = [[random.randint(0, 10) for _ in range(5)] for _ in range(1000000)]
>>> short_ranging = [[random.randint(0, 10) for _ in range(random.randrange(25))] for _ in range(10)]
>>> long_ranging = [[random.randint(0, 10) for _ in range(random.randrange(25))] for _ in range(1000000)]

我正在使用 timeit module 进行测试在 Python 3.6.1rc1 上,在运行 OS X 10.12.3 的 MacBook Pro(Retina,15 英寸,2015 年中)上

然后是每个场景。 Short fixed 是一个包含 10 个嵌套列表的列表,每个列表的长度为 5 个元素。测试时间是 100 万次重复的总和:

>>> timeit('list(map(lambda x:[0]*len(x),l))', 'from __main__ import short_fixed as l')
3.2795075319882017
>>> timeit('list(map(lambda x: list(repeat(0, len(x))), l))', 'from __main__ import short_fixed as l; from itertools import repeat')
6.128518687008182
>>> timeit('[[0] * len(inner) for inner in l]', 'from __main__ import short_fixed as l')
2.254983870021533

长时间固定测试 100 万个元素,重复 10 次以使等待易于管理:

>>> timeit('list(map(lambda x:[0]*len(x),l))', 'from __main__ import long_fixed as l', number=10)
3.955955935991369
>>> timeit('list(map(lambda x: list(repeat(0, len(x))), l))', 'from __main__ import long_fixed as l; from itertools import repeat', number=10)
6.772360901988577
>>> timeit('[[0] * len(inner) for inner in l]', 'from __main__ import long_fixed as l', number=10)
3.302304288983578

可变列表大小介于 0 到 25 个元素之间。短名单:

>>> timeit('list(map(lambda x:[0]*len(x),l))', 'from __main__ import short_ranging as l')
3.155180420988472
>>> timeit('list(map(lambda x: list(repeat(0, len(x))), l))', 'from __main__ import short_ranging as l; from itertools import repeat')
6.213294043001952
>>> timeit('[[0] * len(inner) for inner in l]', 'from __main__ import short_ranging as l')
2.3255828430119436

最后是 100 万个范围列表:

>>> timeit('list(map(lambda x: list(repeat(0, len(x))), l))', 'from __main__ import long_ranging as l; from itertools import repeat', number=10)
8.005676712986315
>>> timeit('list(map(lambda x: list(repeat(0, len(l[0]))), l))', 'from __main__ import long_ranging as l; from itertools import repeat', number=10)
8.49916388199199
>>> timeit('[[0] * len(inner) for inner in l]', 'from __main__ import long_ranging as l', number=10)
3.8087494230130687

在所有情况下,显式循环都更快(高达 2 倍),因为它不必使用 lambda 函数。

如果您准备切换到 numpy 数组,那么该选项可以轻松地将所有内容都抛在脑后。在数组中的所有( native )值上广播乘以 0 会将所有迭代移动到 C,而根本不需要调用函数或执行 Python 字节码:

>>> import numpy
>>> short_fixed_np = numpy.array(short_fixed)
>>> long_fixed_np = numpy.array(long_fixed)
>>> short_ranging_np = numpy.array(short_ranging)
>>> long_ranging_np = numpy.array(long_ranging)
>>> timeit('l = next(copies); l *= 0', 'from __main__ import short_fixed_np as arr, numpy; copies = iter([numpy.copy(arr) for _ in range(10**6)])')
0.8011195910221431
>>> timeit('l = next(copies); l *= 0', 'from __main__ import long_fixed_np as arr, numpy; copies = iter([numpy.copy(arr) for _ in range(10)])', number=10)
0.04912398199667223

(因为这种方法会就地改变对象,所以您需要为每个单独的重复测试创建足够的副本来改变唯一的数组,因此整个 next(copies) 舞蹈)。

要充分利用 numpy 数组也意味着您实际上只能将它们用于固定长度的子列表。对于可变长度子列表,您必须使用对象类型的一维数组(这意味着它们仅用于引用 Python 列表),此时您也不能再将乘法广播到所有数字元素。

请注意,在这种情况下,您必须重组整个项目才能利用 numpy 数组。如果您需要大量访问此类数组中的单个值,请考虑到这会较慢,因为访问单个值需要每次将 C native 值装箱到 Python 对象中。 p>

关于python - 如何将 Python 列表列表的所有值设置为特定值?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42898185/

相关文章:

python - Django 是否支持多值 cookie?

python - 在 QTableWidgetItem 中使用富文本

python - 两点之间的等距点?

python - 从python中的二维列表的所有元素中减去一个值

list - Emacs-Lisp 列表,撇号 ('), and backquote (grave accent, ` )

python - 解析 CSV header

python - 使用 Symfit : typestructure of dataset 进行全局拟合

python-3.x - Python 从列表创建子列表列表

python - 将句子中的单词长度映射到单词列表

python - Python中的无限滚动背景