-3

I have a list with repeated values and need to modify all of those. Notably, the repetitions always occur with a known fixed interval – for example, the 4'th and 5'th, the 9'th and 10'th and so on.

For example, the starting list might look like this:

my_list = [
    'employee',
    'company',
    'value',
    'profit',
    'profit',
    'employee',
    'company',
    'value',
    'profit',
    'profit',
]

Every time a pair of 'profit' items appears, I need to replace them with two new values – one with "12 months" and the other with "3 months" appended. So the output would be like this:

my_list = [
    'employee',
    'company',
    'value',
    'profit 12 months',
    'profit 3 months',
    'employee',
    'company',
    'value',
    'profit 12 months',
    'profit 3 months',
]

So, every 3 and 4 indexes, I want to rename the items in my list.

I know how to edit an item in a list by index, such as my_list[3] = 'profit 12 months'. But my list will be very long and doing this manually would take a lot of time.

How can I operate on every n'th index, especially when there is an initial offset to it?

MisterMiyagi
  • 44,374
  • 10
  • 104
  • 119
  • 3
    So what is the problem you have in doing that? Do you know how to access a list at a specific index and modify the value there? Do you know how to increment an index with 5 repeatedly in a loop? – trincot Jun 27 '22 at 20:00
  • @trincot I know how to access a specific index and modify the value there. But this list is huge. And every 3 and 4 indexes through I have the values that I need to modify. I don't know how to do this (I only know going to a specific index and that would require a lot of work, since is a huge list). I don't know how to increment an index with 5 repeatedly in a loop – interferemadly Jun 27 '22 at 20:02
  • 2
    The `range` function takes an increment argument. You may find this useful. – Chris Jun 27 '22 at 20:03
  • 1
    E.g. `list(range(0, 20, 5))` produces: `[0, 5, 10, 15]` – Chris Jun 27 '22 at 20:05
  • Is the word that can be repeated always "profit"? Does it always appear at the same indices (modulo 5)? Or can it be arbitrary repeated text e.g. "dog" that appears at array indices 231 and 232? – jarmod Jun 27 '22 at 20:06
  • @jarmod Yes, the word is always the same. I just need to add "3 months" or "12 months" in front of it. And yes, always appear at the same indices. The list repeats itself lots of times. – interferemadly Jun 27 '22 at 20:08
  • 2
    This question is being [discussed on meta](https://meta.stackoverflow.com/q/419035). – cigien Jun 30 '22 at 20:57
  • To be extra clear– you have a list, it has "profit" twice at regular intervals, and you simply want to modify each pair of "profit" elements to have the given text at the end. Is that accurate? – zcoop98 Jun 30 '22 at 20:59
  • 1
    @zcoop98 Yes. The thing is that in the first occurrence of "profit", I want to add "12 months". And in the second occurrence of "profit", I want to add "3 months". – interferemadly Jun 30 '22 at 21:02
  • Does https://stackoverflow.com/questions/15909688/assigning-every-nth-element-in-a-list-in-python answer your question? – Karl Knechtel Jul 01 '22 at 10:52

2 Answers2

2

If the indices of the elements to be changed are known (every 5th element starting from 3 etc.), it's irrelevant what that particular value is, using list slicing is enough.

# number of steps
counts = len(my_list) // 5
# change every 5th element starting from 3rd
my_list[3::5] = ['profit 12 months'] * counts
# change every 5th element starting from 4th
my_list[4::5] = ['profit 3 months'] * counts

print(my_list)
# ['employee', 'company', 'value', 'profit 12 months', 'profit 3 months', 'employee', 'company', 'value', 'profit 12 months', 'profit 3 months']
cottontail
  • 10,268
  • 18
  • 50
  • 51
1

If the step size of indices is known but not the value, one can use a range to generate all indices efficiently. A for loop then allows to operate on the elements via the indices:

# iterate over every 5'th index starting at 3
for index in range(3, len(my_list), 5):
    # operate on the list at each selected index
    my_list[index] += " 12 months"

The arguments to range are start, stop, step. Thus we use the first index we want to modify, the length of the list we do not want to exceed, and finally the desired step size between indices.

To modify multiple such index groups, either use multiple loops:

for index in range(3, len(my_list), 5):
    my_list[index] += " 12 months"
for index in range(4, len(my_list), 5):
    my_list[index] += " 3 months"

or – if the step size is the same – derive the smaller index from the larger one.

for index in range(4, len(my_list), 5):
    my_list[index-1] += " 12 months"
    my_list[index] += " 3 months"
MisterMiyagi
  • 44,374
  • 10
  • 104
  • 119