Home > Net >  How to iterate through a list with different start and stop indices in Python?
How to iterate through a list with different start and stop indices in Python?

Time:03-05

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)
  • Related