for i in range(15):
print i #will print out 0..14
for i in range(1, 15):
print i # will print out 1..14
for i in range (a, b, s):
print i # will print a..b-1 counting by s. interestingly if while counting by the step 's' you exceed b, it will stop at the last 'reachable' number, example
for i in range(1, 10, 3):
print i
> 1
> 4
> 7
List Splicing:
a = "hello" # there are 5 characters, so the characters are accessible on indexes 0..4
a[1] = 'e'
a[1:2] = 'e' # because the number after the colon is not reached.
a[x:y] = all characters starting from the character AT index 'x' and ending at the character which is before 'y'
a[x:] = all characters starting from x and to the end of the string
In the future, if you ever wonder what the behavior of python is like, you can try it out in the python shell. just type python in the terminal and you can enter any lines you want (though this is mostly convenient for one-liners rather than scripts).
Answer from Jeremy Fisher on Stack Overflowfor i in range(15):
print i #will print out 0..14
for i in range(1, 15):
print i # will print out 1..14
for i in range (a, b, s):
print i # will print a..b-1 counting by s. interestingly if while counting by the step 's' you exceed b, it will stop at the last 'reachable' number, example
for i in range(1, 10, 3):
print i
> 1
> 4
> 7
List Splicing:
a = "hello" # there are 5 characters, so the characters are accessible on indexes 0..4
a[1] = 'e'
a[1:2] = 'e' # because the number after the colon is not reached.
a[x:y] = all characters starting from the character AT index 'x' and ending at the character which is before 'y'
a[x:] = all characters starting from x and to the end of the string
In the future, if you ever wonder what the behavior of python is like, you can try it out in the python shell. just type python in the terminal and you can enter any lines you want (though this is mostly convenient for one-liners rather than scripts).
The best way to clarify such doubts is to play with the REPL:
>>> range(10)
range(0, 10)
>>> list(range(10))
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> x = list(range(10))
>>> x[:3]
[0, 1, 2]
>>> x[:1]
[0]
>>> x[1:10]
[1, 2, 3, 4, 5, 6, 7, 8, 9]
Is range(len(list)) ever Pythonic?
How to get the index range of a list that the values satisfy some criterion in Python? - Stack Overflow
python - how to extract a range of index from a list - Stack Overflow
Droping data with range of negitive indexes
Videos
Are there circumstances where for i in range(len(my_list)): is to be preferred over for i, _ in enumerate(my_list):? If so, what are they, generally speaking?
Edited to fix syntax.
a = [12,11,5,7,2,21,32,13,6,42,1,8,9,0,32,38]
indices = [idx for idx,val in enumerate(a) if val < 10]
This creates a list of indices:
[2, 3, 4, 8, 10, 11, 12, 13]
I would recommend keeping it that way for easy parsing, but you can also turn it into ranges as follows:
ranges = [[]]
for val in indices:
if not ranges[-1] or ranges[-1][-1] == val-1:
ranges[-1].append(val)
else:
ranges.append([val])
This creates a list of ranges:
[[2, 3, 4], [8], [10, 11, 12, 13]]
Now to take out the middle:
ranges = [[item[0],item[-1]] if len(item) > 1 else item for item in ranges]
Result:
[[2, 4], [8], [10, 13]]
You can have your function take a function as an argument to use as the predicate for building your intervals:
def indexscope(dlist, predicate):
scope = []
start = end = -1
for i, v in enumerate(dlist):
if predicate(v):
if start == -1:
start = end = i
continue
if end + 1 == i:
end = i
else:
scope.append([start] if start == end else [start, end])
start = end = i
if start != -1:
scope.append([start] if start == end else [start, end])
return scope
a = [12,11,5,7,2,21,32,13,6,42,1,8,9,0,32,38]
def less_than_10(n):
return n < 10
print(indexscope(a, less_than_10))
print(indexscope(a, lambda x: x > 20))
[[2, 4], [8], [10, 13]]
[[5, 6], [9], [14, 15]]
with scipy:
import numpy as np
import scipy.ndimage as nd
def passing_ranges(a, predicate):
return nd.find_objects(nd.label(predicate(a))[0])
The results are returned as slice objects, but that is to your advantage because you can use them to against your original np array:
small_a = [12,11,5,7,2,21,32,13,6,42,1,8,9,0,32,38]
small_np_array = np.array(small_a)
valid_ranges = passing_ranges(small_np_array, lambda n: n < 10)
for r in valid_ranges:
print(r[0], small_np_array[r])
slice(2, 5, None) [5 7 2]
slice(8, 9, None) [6]
slice(10, 14, None) [1 8 9 0]
benchmarks
large_a = [12,11,5,7,2,21,32,13,6,42,1,8,9,0,32,38]*1000000
large_np_array = np.array(large_a)
%timeit passing_ranges(large_np_array, lambda x: x < 10)
1 loops, best of 3: 1.2 s per loop
%timeit indexscope(large_a, lambda n: n < 10)
1 loops, best of 3: 6.99 s per loop
Here is your answer, I even inline the predicate to remove a function call:
from itertools import groupby, count
def xibinke(a):
l = [idx for idx,value in enumerate(a) if value<10]
return [list(g) for _,g in groupby(l,key=lambda n,c=count():n-next(c))]
%timeit xibinke(large_a)
1 loops, best of 3: 14.6 s per loop
One alternative is to do:
mylist1 = [11, 4, 5, 6, 8, 6, 3]
for i in mylist1:
a = list(range(i))
print(a[-2:] + a[:2])
Output
[9, 10, 0, 1]
[2, 3, 0, 1]
[3, 4, 0, 1]
[4, 5, 0, 1]
[6, 7, 0, 1]
[4, 5, 0, 1]
[1, 2, 0, 1]
You could try something like this:
list1 = [0, 1, 2, 3, 4, 5]
for ln in range(1, len(list1)):
list2 = [list1[n] for n in range(-ln, ln)] #magic line
print(list2)
or you could also try this instead of the magic line:
list2 = list1[ln:] + list1[:ln]
Where ln is the number of elements you want from the end and the beginning of the list.