I have a startnumber and an endnumber.
From these numbers I need to pick a sequence of numbers.
The sequences is not always the same.
Example:
startnumber = 1
endnumber = 32
I need to create a list of numbers with a certain sequence
pe
3 numbers yes, 2 numbers no, 3 numbers yes, 2 numbers no.. etc
Expected output:
[[1-3],[6-8],[11-13],[16-18],[21-23],[26-28],[31-32]]
(at the end there are only 2 numbers remaining (31 and 32))
Is there a simple way in python to select sequences of line from a range of numbers?
numbers = range(1,33)
take = 3
skip = 2
seq = [list(numbers[idx:idx+take]) for idx in range(0, len(numbers),take+skip)]
Extrapolating this out:
def get_data(data, filterfunc=None):
if filterfunc is None:
filterfunc = lambda: True # take every line
result = []
sub_ = []
for line in data:
if filterfunc():
sub_.append(line)
else:
if sub_:
result.append(sub_)
sub_ = []
return result
# Example filterfunc
def example_filter(take=1, leave=1):
"""example_filter is a less-fancy version of itertools.cycle"""
while True:
for _ in range(take):
yield True
for _ in range(leave):
yield False
# Your example
final = get_data(range(1, 33), example_filter(take=3, leave=2))
As alluded to in the docstring of example_filter, the filterfunc
for get_data is really just expecting a True
or False
based on a call. You could change this easily to be of the signature:
def filterfunc(some_data: object) -> bool:
So that you can determine whether to take or leave based on the value (or even the index), but it currently takes no arguments and just functions as a less magic itertools.cycle
(since it should return its value on call, not on iteration)
from itertools import islice
def grouper(iterable, n, min_chunk=1):
it = iter(iterable)
while True:
chunk = list(islice(it, n))
if len(chunk) < min_chunk:
return
yield chunk
def pick_skip_seq(seq, pick, skip, skip_first=False):
if skip_first:
ret = [ x[skip:] for x in grouper(seq, pick+skip, skip+1) ]
else:
ret = [ x[:pick] for x in grouper(seq, pick+skip) ]
return ret
pick_skip_seq(range(1,33), 3, 2)
gives required list.
In pick_skip_seq(seq, pick, skip, skip_first=False)
, seq
is sequence to pick/skip from, pick
/ skip
are no. of elements to pick/skip, skip_first
is to be set True
if such behavior is desired.
grouper
returns chunks of n elements, it ignores last group if it has less than min_chunk elements. It is derived from stuff given in https://stackoverflow.com/a/8991553/1921546 .
Demo:
# pick 3 skip 2
for i in range(30,35):
print(pick_skip_seq(range(1,i), 3, 2))
# skip 3 pick 2
for i in range(30,35):
print(pick_skip_seq(range(1,i), 3, 2, True))
An alternative implementation of pick_skip_seq
:
from itertools import chain,cycle,repeat,compress
def pick_skip_seq(seq, pick, skip, skip_first=False):
if skip_first:
c = cycle(chain(repeat(0, skip), repeat(1, pick)))
else:
c = cycle(chain(repeat(1, pick), repeat(0, skip)))
return list(grouper(compress(seq, c), pick))
All things used are documented here: https://docs.python.org/3/library/itertools.html#itertools.compress
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.