在python列表解析中解包元组(未使用*-operator)

DRz*_*DRz 12 python tuples list-comprehension iterable-unpacking

我试图基于另一个列表创建一个列表,相同的值连续重复3次.

目前,我正在使用:

>>> my_list = [ 1, 2 ]
>>> three_times = []
>>> for i in range( len( my_list ) ):
...   for j in range( 3 ):
...     three_times.append( my_list[ i ] )
...
>>> print three_times
[1, 1, 1, 2, 2, 2]
Run Code Online (Sandbox Code Playgroud)

但我想用更Pythonic的方式来做,例如:

>>> my_list = [ 1, 2 ]
>>> three_times = []
>>> three_times = [ (value,) * 3 for value in my_list ]
>>> print three_times
[(1, 1, 1), (2, 2, 2)]
Run Code Online (Sandbox Code Playgroud)

但是,我找不到解开元组的方法.

类似的东西three_times = [ *( (value,) * 3 ) for value in my_list ]对于解包元组是完美的,但这不是一个正确的语法.

Mar*_*ers 15

您不能*在列表推导中使用可迭代解包,该语法仅在调用中可用,而在Python 3中,在使用赋值时.

如果你想使用列表推导,只需将你的for循环串联; 你确实希望my_list直接访问值而不是生成索引:

[v for v in my_list for _ in range(3)]
Run Code Online (Sandbox Code Playgroud)

  • 有什么想法吗?即使在 2021 年,这也是不可能的,而且我没有看到这样的语法有任何歧义...... (10认同)
  • @karlosss:由于对可读性的强烈关注,它被从 PEP 448 中删除,请参阅[变体部分](https://www.python.org/dev/peps/pep-0448/#variations)。 (4认同)
  • @nyuszika7h:如果您想辩论该决定,请将其带到 [Python 讨论板](https://discuss.python.org/) 或邮件列表。此处的评论仅用于帮助管理问题和答案。 (2认同)

pai*_*ime 5

接受的答案是正确的,但我做了一些效率测试,所以分享给路人。

摘要:使用chain.from_iterable了〜在列表理解X2的速度提升。和使用np.repeat用于〜5233的速度提高,如果你不介意的进口numpy,但不要使用np.repeat,如果最终转换回list

In [1]: from itertools import chain
   ...: import numpy as np
   ...: 
   ...: def nested_list_comprehension(seq, repeats):
   ...:     return [v for v in seq for _ in range(repeats)]
   ...: 
   ...: def chain_from_iterable_tuple(seq, repeats):
   ...:     return list(chain.from_iterable((v,) * repeats for v in seq))
   ...: 
   ...: def chain_from_iterable_list(seq, repeats):
   ...:     return list(chain.from_iterable([v] * repeats for v in seq))
   ...: 
   ...: def numpy_repeat_list(seq, repeats):
   ...:     return list(np.repeat(seq, repeats))
   ...: 
   ...: def numpy_repeat(seq, repeats):
   ...:     return np.repeat(seq, repeats)

In [2]: seq = list(range(1000))
   ...: repeats = 100

In [3]: assert (
   ...:     nested_list_comprehension(seq, repeats)
   ...:     == chain_from_iterable_tuple(seq, repeats)
   ...:     == chain_from_iterable_list(seq, repeats)
   ...:     == numpy_repeat_list(seq, repeats)
   ...: )

In [4]: %timeit nested_list_comprehension(seq, repeats)
   ...: %timeit chain_from_iterable_tuple(seq, repeats)
   ...: %timeit chain_from_iterable_list(seq, repeats)
   ...: %timeit numpy_repeat_list(seq, repeats)
   ...: %timeit numpy_repeat(seq, repeats)
1.53 ms ± 2.9 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
814 µs ± 3.79 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
842 µs ± 2.02 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
3.65 ms ± 22.3 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
268 µs ± 1.44 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
Run Code Online (Sandbox Code Playgroud)