Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/358.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/list/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python-用于列表生成的[k]*n的变体_Python_List_Python 2.7 - Fatal编程技术网

Python-用于列表生成的[k]*n的变体

Python-用于列表生成的[k]*n的变体,python,list,python-2.7,Python,List,Python 2.7,给定一个元素列表[1,27,10,…]我需要生成一个每个元素的n重复列表,如[1,1,…,1,27,27,…,27,10,…,10] 做这件事最优雅、最通俗、最快的方法是什么 回答 numpy是最快、最简洁的解决方案 np.repeat(my_list,n)看起来非常像蟒蛇(归功于B.M.),而展平numpy数组似乎要快一些 也可以看看B.M.帖子下面的numba备选方案 更多细节 我测试了3种方法:I)双循环,ii)带索引功能的单循环,以及iii)展平numpy数组。(编辑:Mike使用ext

给定一个元素列表
[1,27,10,…]
我需要生成一个每个元素的
n
重复列表,如[
1,1,…,1,27,27,…,27,10,…,10]

做这件事最优雅、最通俗、最快的方法是什么

回答

numpy
是最快、最简洁的解决方案

np.repeat(my_list,n)
看起来非常像蟒蛇(归功于B.M.),而展平numpy数组似乎要快一些

也可以看看B.M.帖子下面的
numba
备选方案

更多细节

我测试了3种方法:I)双循环,ii)带索引功能的单循环,以及iii)展平numpy数组。(编辑:Mike使用
extend
,第四次进近使用
np,第五次进近使用
np。B.M.重复
,gsb eng理解第六次进近,第七次进近使用itertools)

令人惊讶的是,我发现在我的机器上,用python 2.7展平数组是迄今为止最快的方法。然而,在某些机器和Python 3中,您可能需要测试itertools和理解。您可以复制/粘贴下面的Python 2代码以进行快速检查,排序后的
timeit
结果如下:

Flattened array: 8.8ms
Numpy Repeat: 10.87ms
Extend List: 14.37ms
Itertools Repeat: 14.91ms
Itertools  Chain Comprehension: 18.72ms
Itertools Chain: 18.73ms
Double Loop : 58.4ms
Single Loop + index by division: 251.29ms
Double Loop + comprehension: 255.76ms
这是生成结果的代码:

import numpy as np

import timeit

n = 100

my_list = range(10)
n_elements = len(my_list)

# === Double Loop =============================================================
def double_loop():
    my_long_list = []

    for list_element in my_list:
        my_long_list += [list_element] * n

    return my_long_list

# === Double Loop with Comprehension =========================================================    
def double_loop_comp():

    # List comprehension
    return [i for i in my_list for j in xrange(n)]   

# === Single Loop with Indexing Function ======================================
def one_loop_with_indexing():
    my_long_list = []

    for i in range(n*n_elements):
        my_long_list.append(my_list[i // n]) 


    return my_long_list

# === Flattened Array =========================================================
def flattened_array():
    my_array = np.zeros([n_elements, n])

    for i in range(n_elements):
        my_array[i,:] = my_list[i]

    return my_array.flatten()

# === Extend List =========================================================
def extend_list():
    my_long_list = []
    for list_element in my_list:
        my_long_list.extend([list_element] * n)
    return my_long_list

# === Numpy Repeat =========================================================
def numpy_repeat():
    return np.repeat(my_list, n)

# === Itertools Repeat ========================================================
def iter_repeat():
    my_long_list = []
    for x in my_list:
        my_long_list.extend( itertools.repeat(x,n) )
    return my_long_list

# === Itertools Chain =========================================================
def iter_chain():
    return list( itertools.chain.from_iterable( itertools.repeat(x,n) for x in my_list ) )

# === Itertools Chain Comp ====================================================
def iter_chain_comp():
    return list( itertools.chain.from_iterable( [itertools.repeat(x,n) for x in my_list] ) )



time_double_loop = timeit.timeit(double_loop, number=1000)
time_double_loop_comp = timeit.timeit(double_loop_comp, number=1000)
time_single_loop = timeit.timeit(one_loop_with_indexing, number=1000)
time_flattened_array = timeit.timeit(flattened_array, number=1000)
time_extend_list = timeit.timeit(extend_list, number=1000)
time_np_repeat = timeit.timeit(numpy_repeat, number=1000)
time_it_repeat = timeit.timeit(iter_repeat, number=1000)
time_it_chain = timeit.timeit(iter_chain, number=1000)
time_it_chain_comp = timeit.timeit(iter_chain_comp, number=1000)

print 'Double Loop : ' + str(round(time_double_loop*1000,2))+'ms'
print 'Double Loop + comprehension: ' + str(round(time_double_loop_comp*1000,2))+'ms'
print 'Single Loop + index by division: ' + str(round(time_single_loop*1000,2))+'ms'
print 'Flattened array: ' + str(round(time_flattened_array*1000,2))+'ms'
print 'Extend List: ' + str(round(time_extend_list*1000,2))+'ms'
print 'Numpy Repeat: ' + str(round(time_np_repeat*1000,2))+'ms'
print 'Itertools Repeat: ' + str(round(time_it_repeat*1000,2))+'ms'
print 'Itertools Chain: ' + str(round(time_it_chain*1000,2))+'ms'
print 'Itertools  Chain Comprehension: ' + str(round(time_it_chain_comp*1000,2))+'ms'
您可以使用
extend()

在我的机器上速度更快:

Double Loop :0.0226180553436
Single Loop + indexing function: 0.300093889236
Flattened array: 0.0395331382751
Extend List: 0.0189819335938
列出正确结果的理解:

def double_loop_comp():
    return [i for i in my_list for j in xrange(n)]
列表理解速度较慢:

Double Loop :0.016893863678
Single Loop + indexing function: 0.300258874893
Flattened array: 0.0327677726746
Extend List: 0.0180258750916
Comp: 0.0602869987488

我已将
展平数组
替换为本机
列表理解

[i for i in my_list for j in xrange(n)]
对于这种情况,这是一种更具
pythonic
风格的解决方法

下面是相同的
timeit
结果

Double Loop :0.0249750614166
Single Loop + indexing function: 0.198489904404
List comprehension: 0.00534200668335
下面是在代码中添加
列表理解
条目后的完整代码

import timeit

n = 100

my_list = range(10)
n_elements = len(my_list)

# === Double Loop =============================================================
def double_loop():
    my_long_list = []

    for list_element in my_list:
        my_long_list += [list_element] * n

    return my_long_list

def double_loop_comp():

    # List comprehension
    return [i for i in my_list for j in xrange(n)]

# === Single Loop with Indexing Function ======================================
def one_loop_with_indexing():
    my_long_list = []

    for i in range(n*n_elements):
        my_long_list.append(my_list[i / n])  # !! This would not work if you use "from __future__ import division"


    return my_long_list


time_double_loop = timeit.timeit(double_loop, number=1000)
time_single_loop = timeit.timeit(one_loop_with_indexing, number=1000)
time_double_loop_comp = timeit.timeit(double_loop_comp, number=1000)

print 'Double Loop :' + str(time_double_loop)
print 'Single Loop + indexing function: ' + str(time_single_loop)
print 'List comprehension: ' + str(time_double_loop_comp)

如果结果必须是可编辑的,但不必是列表,则可以通过仅创建生成器来“作弊”:

import itertools as it

def make_generator():
    return it.chain.from_iterable(it.repeat(elem, n) for elem in my_list)

在fast类别中,使用
a=np.array(my_list)
(测试中的100个元素):

可读:

In [12]: %timeit np.repeat(a,100)
10000 loops, best of 3: 80.4 µs per loop
棘手的:

In [13]: %timeit np.lib.stride_tricks.as_strided(a,(100,100),(a.itemsize,0)).ravel()
10000 loops, best of 3: 29.5 µs per loop
使用numba进行即时编译(在
conda安装numba之后)


你也可以使用itertools来获取列表,而且在我的机器上是最快的

import itertools as it
n = 100
my_list = range(10)
n_elements = len(my_list)

def iter_repeat():
    my_long_list = []
    for x in my_list:
        my_long_list.extend( it.repeat(x,n) )
    return my_long_list

def iter_chain():
    return list( it.chain.from_iterable( it.repeat(x,n) for x in my_list ) )

def iter_chain_comp():
    return list( it.chain.from_iterable( [it.repeat(x,n) for x in my_list] ) )
使用您的脚本来测试它,我在python3中得到了这一次

Double Loop :                     0.015303148491881732
Double Loop + comprehension :     0.04365179467151968
Single Loop + index by division:  0.3784320416645417
Extend List:                      0.01603116899830609
Flattened array:                  0.018885064147608488
Numpy Repeat:                     0.0254420405658366
Itertools repeat extend:          0.015163157712790254
Itertools chain repeat:           0.025397544719181653
Itertools chain repeat comp:      0.025096342064901633

order
0.015163157712790254 time_iter_repeat
0.015303148491881732 time_double_loop
0.01603116899830609 time_extend_list
0.018885064147608488 time_flattened_array
0.025096342064901633 time_iter_chain_comp
0.025397544719181653 time_iter_chain
0.0254420405658366 time_np_repeat
0.04365179467151968 time_double_loop_comp
0.3784320416645417 time_single_loop
在python 2中,我得到了

Double Loop :                     0.0188628162243
Double Loop + comprehension :     0.069114371782
Single Loop + index by division:  0.239681327592
Extend List:                      0.0197920948679
Itertools repeat extend:          0.0275025405417
Itertools chain repeat:           0.0315609040324
Itertools chain repeat comp:      0.0317361492131

order
0.0188628162243 time_double_loop
0.0197920948679 time_extend_list
0.0275025405417 time_iter_repeat
0.0315609040324 time_iter_chain
0.0317361492131 time_iter_chain_comp
0.069114371782 time_double_loop_comp
0.239681327592 time_single_loop

(我在python2中没有numpy,安装它很痛苦,所以我不做那个测试)

扁平化的数组
可能更快,因为您使用的是
numpy
arraynumpy是为了提高效率,所以毫不奇怪。有一个numpy函数可以直接执行此操作:
np.repeat(my_list,n)
对于我来说,双循环是最快的。对于整数除法,请使用
/
。理解仍然是错误的。将
xrange(n_元素)
更改为
xrange(n)
,然后再试一次。啊,你说得对,现在速度慢多了。再次编辑。谢谢你发现这篇文章谢谢迈克,会编辑这篇文章的,在我的机器上,扁平的_阵列似乎比原来的文章快了2倍谢谢。np在我的机器上似乎仍然更快,尽管agree native comprehension更像Python,但它不会给出相同的结果
assert double\u loop\u comp()==double\u loop()
-->`AssertionError@MikeMüller我试图给出
pythonic
解决方案,显然,添加
numpy
不是一个
pythonic
解决方案,对吗?@pythonic:我不知道,但在我的机器中
理解
是赢家<代码>双循环:0.0179278850555双循环+理解:0.0077600479126单循环+按除法索引:0.174581050873扁平数组:0.0127079486847扩展列表:0.0113019943237 Numpy重复:0.01116000175476
@Pythonic BTW,您必须在
python2.x
中检查此项,对吗?谢谢,我需要一个列表(实际上,它是在熊猫中完成的工作的索引器)没有可用的文档:这里有一些很好的
使用示例:添加了上面的itertools,在我的机器上扁平化速度仍然最快。可能是python 2对3吗?是的,它可能是许多类似python 2对3的东西,因为在我的机器中,双循环在2中获胜(没有numpy)但是iter_repeat在3中获胜(使用numpy),机器和操作系统也可以发挥作用,my是一款带有Windons的双核3GHz
Double Loop :                     0.015303148491881732
Double Loop + comprehension :     0.04365179467151968
Single Loop + index by division:  0.3784320416645417
Extend List:                      0.01603116899830609
Flattened array:                  0.018885064147608488
Numpy Repeat:                     0.0254420405658366
Itertools repeat extend:          0.015163157712790254
Itertools chain repeat:           0.025397544719181653
Itertools chain repeat comp:      0.025096342064901633

order
0.015163157712790254 time_iter_repeat
0.015303148491881732 time_double_loop
0.01603116899830609 time_extend_list
0.018885064147608488 time_flattened_array
0.025096342064901633 time_iter_chain_comp
0.025397544719181653 time_iter_chain
0.0254420405658366 time_np_repeat
0.04365179467151968 time_double_loop_comp
0.3784320416645417 time_single_loop
Double Loop :                     0.0188628162243
Double Loop + comprehension :     0.069114371782
Single Loop + index by division:  0.239681327592
Extend List:                      0.0197920948679
Itertools repeat extend:          0.0275025405417
Itertools chain repeat:           0.0315609040324
Itertools chain repeat comp:      0.0317361492131

order
0.0188628162243 time_double_loop
0.0197920948679 time_extend_list
0.0275025405417 time_iter_repeat
0.0315609040324 time_iter_chain
0.0317361492131 time_iter_chain_comp
0.069114371782 time_double_loop_comp
0.239681327592 time_single_loop