简体   繁体   English

在 python 列表推导中解包元组(不能使用 *-operator)

[英]Unpacking tuples in a python list comprehension (cannot use the *-operator)

I am trying to create a list based on another list, with the same values repeated 3 times consecutively.我正在尝试基于另一个列表创建一个列表,相同的值连续重复 3 次。

At the moment, I am using:目前,我正在使用:

>>> 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]

But I would like to do it using a more Pythonic way, such as:但我想使用更 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)]

However, I cannot find a way to unpack the tuples.但是,我找不到解包元组的方法。

Something like three_times = [ *( (value,) * 3 ) for value in my_list ] would be perfect for unpacking the tuples but this is not a correct syntax.three_times = [ *( (value,) * 3 ) for value in my_list ]之类的东西非常适合解包元组,但这不是正确的语法。

You can't use * iterable unpacking in a list comprehension, that syntax is only available in calls, and in Python 3, when using assignments.您不能在列表推导式中使用*可迭代解包,该语法仅在调用中可用,在 Python 3 中使用赋值时可用。

If you want to use a list comprehension, just put your for loops in series;如果您想使用列表推导式,只需将您的for循环串联起来即可; you do want to access the values from my_list directly rather than generate indices though:您确实想直接从my_list访问值,而不是生成索引:

[v for v in my_list for _ in range(3)]

Accepted answer is correct, but I made some efficiency tests, so sharing it for passers-by.接受的答案是正确的,但我做了一些效率测试,所以分享给路人。

Summary: Use chain.from_iterable for ~x2 speed improvement over list comprehension.总结:使用chain.from_iterable比列表理解提高 ~x2 速度。 And use np.repeat for ~x6 speed improvement if you don't mind importing numpy , but don't use np.repeat if eventually converting back to list .和使用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)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM