I have two lists:
nums = [2, 4, 5, 3, 6]
a = [64, 64, 64, 64, 64, 56, 56, 56, 63, 63, 63, 63, 63, 64, 66, 66, 66]
I want to iterate through the list a
using the nums
list. The first time, I want to iterate through the first two digits of a because that's the first number in nums
. Then, I want to iterate through the next four elements in a
since that's the second element in nums
and so on.
Basically, iterate through [0, 2], [2, 4 2], [4 2, 4 2 5], [4 2 5, 4 2 5 3] of a
. The numbers in nums
are the number of elements I want to iterate through in a
.
I then want to get the majority of the elements in a
within that start and stop index. So, I did this:
li = []
start = 0
stop = nums[0]
for j in range(len(nums)):
for item in itertools.islice(labels, start, nums[j]):
li.append(item)
c = Counter(li)
c.most_common()
value, count = c.most_common()[0]
print(value)
How do I change the start and stop indices though? Thanks!
CodePudding user response:
How about this, using an iterator to read items from a
instead of trying to figure out the indices?
nums = [2, 4, 5, 3, 6]
a = [64, 64, 64, 64, 64, 56, 56, 56, 63, 63, 63, 63, 63, 64, 66, 66, 66]
aa = iter(a)
try:
for n in nums:
li = [next(aa) for _ in range(n)]
# do whatever with these few elements
except StopIteration:
# the contents of `nums` exceeded the length of `a`
pass
CodePudding user response:
You'd probably want to use itertools.accumulate
, as you're trying to iterate through the list in partial-sum indices, something like this should work:
import itertools
from collections import Counter
for start, end in zip([0] nums, itertools.accumulate(nums)):
c = Counter(a[start:end])
print(c.most_common()[0][0]) # This is the value
The zip(...)
operation allows you to iterate pairs of start-stop indices, and the [0]
at the beginning ensures that the first slice you iterate through is [0, nums[0]]
CodePudding user response:
Getting the slices with itertools.islice
:
it = iter(a)
for num in nums:
print(*islice(it, num))
Or without:
i = 0
for num in nums:
print(a[i : (i := i num)])
Respective outputs (Try it online!):
64 64
64 64 64 56
56 56 63 63 63
63 63 64
66 66 66
[64, 64]
[64, 64, 64, 56]
[56, 56, 63, 63, 63]
[63, 63, 64]
[66, 66, 66]
CodePudding user response:
Here is a re-write of the @GreenCloakGuy's asnwer.
You can write a generator which yields chunks like:
def get_slices(iterable, numbers):
it = iter(iterable)
for n in numbers:
yield [next(it) for _ in range(n)]
The above will raise exception if you put incorrect values in numbers
. If this is not your case you can have an option to silent it like what islice
does:
def get_slices(iterable, numbers, silent=True):
it = iter(iterable)
for n in numbers:
if silent:
try:
yield [next(it) for _ in range(n)]
except StopIteration:
return
else:
yield [next(it) for _ in range(n)]
test:
def get_slices(iterable, numbers, silent=True):
it = iter(iterable)
for n in numbers:
if silent:
try:
yield [next(it) for _ in range(n)]
except StopIteration:
return
else:
yield [next(it) for _ in range(n)]
nums = [2, 4, 5, 3, 6]
a = [64, 64, 64, 64, 64, 56, 56, 56, 63, 63, 63, 63, 63, 64, 66, 66, 66]
for i in get_slices(a, nums, silent=True):
print(i)
output:
[64, 64]
[64, 64, 64, 56]
[56, 56, 63, 63, 63]
[63, 63, 64]
CodePudding user response:
Here is a slight modification to your code that changes the start and stop indices as you've asked:
import itertools
from collections import Counter
nums = [2, 4, 5, 3, 6]
a = [64, 64, 64, 64, 64, 56, 56, 56, 63, 63, 63, 63, 63, 64, 66, 66, 66]
li = []
start = 0
stop = nums[0]
for j in range(len(nums)):
for item in itertools.islice(a, start, stop):
li.append(item)
c = Counter(li)
c.most_common()
value, count = c.most_common()[0]
if j 1 < len(nums):
start = stop
stop = nums[j 1]
print(value)