2013-12-06 3 views
0

Мне нужно создать список размеров N из уже предоставленного списка.Python-Как создать список из N элементов из данного списка

N = 3 
a_list = [10,4,18,2,6,19,24,1,20] 

O/P должно быть:

[10,4,18] [4,18,2] [18,2,6] [2,6,19] [6,19,24] [19,24,1] [24,1,20] 

Это как размер окна N = 3, который скользит один шаг справа.

Как мне это сделать?

+0

нет, что будет получить '[10,4,18], [2,6,19], [24,1,20]' –

+1

@alko - Я проверил эту тему уже. Но проблема была другая – PythonEnthusiast

ответ

5

Более быстрый способ:

>>> zip(a_list,a_list[1:],a_list[2:]) 
[(10, 4, 18), (4, 18, 2), (18, 2, 6), (2, 6, 19), (6, 19, 24), (19, 24, 1), (24, 1, 20)] 

Сравнение:

In [6]: %timeit [a_list[i:i+n] for i in xrange(len(a_list)-n+1)] 
100000 loops, best of 3: 9.61 us per loop 

In [7]: %timeit zip(a_list,a_list[1:],a_list[2:]) 
100000 loops, best of 3: 5.23 us per loop 

Или более общий:

>>> zip(*[a_list[i:] for i in range(3)]) #3 (or 2, 4, 5, etc)is the length of step 

Для больших list, вероятно, вам придется использовать numpy, чтобы получить более быстрое решение, чем @Ashwini Чаудхари (в http://www.rigtorp.se/2011/01/01/rolling-statistics-numpy.html):

import numpy as np 
lista=np.array(lis) 
def rolling_window(a, window): 
    shape = a.shape[:-1] + (a.shape[-1] - window + 1, window) 
    strides = a.strides + (a.strides[-1],) 
    return np.lib.stride_tricks.as_strided(a, shape=shape, strides=strides) 

%timeit [lis[i:i+n] for i in xrange(len(lis)-n+1)] 
%timeit rolling_window(lista, n) 

1 loops, best of 3: 171 ms per loop 
100000 loops, best of 3: 19.7 µs per loop 
+0

Что делать, если у меня есть n = 5? – PythonEnthusiast

+0

Здесь вы можете перейти к редактированию. –

+0

Пожалуйста, объясните. как будет 'zip (* [a_list [i:] для i в диапазоне (3)])' справедливо для n = 5 – PythonEnthusiast

5

Используйте список понимание и нарезка:

>>> lis = [10,4,18,2,6,19,24,1,20] 
>>> n = 3 
>>> [lis[i:i+n] for i in xrange(len(lis)-n+1)] 
[[10, 4, 18], [4, 18, 2], [18, 2, 6], [2, 6, 19], [6, 19, 24], [19, 24, 1], [24, 1, 20]] 
>>> n = 4 
>>> [lis[i:i+n] for i in xrange(len(lis)-n+1)] 
[[10, 4, 18, 2], [4, 18, 2, 6], [18, 2, 6, 19], [2, 6, 19, 24], [6, 19, 24, 1], [19, 24, 1, 20]] 

Для большего списка подход, основанный на zip на самом деле медленнее:

In [27]: n = 100                     

In [28]: lis = [10,4,18,2,6,19,24,1,20]*10000              

In [30]: %timeit zip(*[lis[i:] for i in xrange(n)])            
1 loops, best of 3: 593 ms per loop                

In [31]: %timeit [lis[i:i+n] for i in xrange(len(lis)-n+1)]          
10 loops, best of 3: 114 ms per loop  
+1

Dang, я немного опоздал. +1 сэр. – aIKid

+0

Спасибо. На самом деле я тоже думал об использовании нарезки, но не был ясен в своих мыслях. Благодарю. – PythonEnthusiast

+0

Теперь у меня строка в моем файле как '10 4 18 2 6 19 24 1 20'. Я могу прочитать эту строку, но как мне преобразовать эту «Линию» в список? – PythonEnthusiast

0

попробовать этот

>>> lis = [10,4,18,2,6,19,24,1,20] 
>>> n=3 
>>> [lis[i:i+n] for i in range(len(lis))][:-2] 

выход

[[10, 4, 18], [4, 18, 2], [18, 2, 6], [2, 6, 19], [6, 19, 24], [19, 24, 1], [24, 1, 20]] 
Смежные вопросы