0

How would you 1) insert 1's between any two adjacent 5's? and then 2) insert a value into the second list at the same index as the 1 that was inserted into the first list?

For example,

list1 = [  5,   1,   5,   5,   5,   1,  etc.] 

would become

list1 = [  5,   1,   5,   1,   5,   1,   5,   1,  etc.]

And,

list2 = [ val, val, val, val, val, val, etc.] 

would become

list2 = [ val, val, val, Nval, val, Nval, etc.]

(Nval up above = the added value)

I'm a beginner so help is greatly appreciated :O)

ddog
  • 39
  • 5

5 Answers5

2

You'll want to look at pairs of consecutive values. To do that, let's pair the list with the last item cut off (list[:-1]) with again the list, but with the first item cut off (list[1:]). (The slice notation used here is being introduced in the official Python tutorial and explained in this answer.)

zip(list1[:-1], list1[1:])

(The zip function turns a pair of sequences into a sequence of pairs and is introduced here in the tutorial and documented here.)

Let's see which these pairs are (5, 5):

[pair == (5, 5) for pair in zip(list1[:-1], list1[1:])]

The feature used here is a list comprehension, a way of writing a (new) list by giving a rule to construct it from an existing iterable.

What are the indices of these pairs? Let's number them with enumerate:

[n for (n, pair) in enumerate(zip(list1[:-1], list1[1:])) if pair == (5, 5)]

This is another list comprehension, this time with a condition for the elements (a "predicate"). Note that enumerate returns pairs of numbers and values (which are our original pairs), and that we use implicit unpacking to get them into the loop variables n and pair respectively.

list.insert(i, new_value) takes the index after which the new value shall be inserted. Thus to find the positions where to insert into the original list (and into list2), we need to add 1 to the pair indices:

idxs = [n + 1 for (n, pair) in enumerate(zip(list1[:-1], list1[1:])) if pair == (5, 5)]

for i in reversed(idxs):
    list1.insert(idxs, 1)
    list2.insert(idxs, 'Nval')

(We insert in reverse order, so as to not move the pairs between which we have yet to insert.)

das-g
  • 9,718
  • 4
  • 38
  • 80
1

You can recover the insertion indices with a single list comprehension. You are looking for indices i such that 5 == list1[i-1] == list1[i].

You then need to insert in decreasing order of indices.

list1 = [5,   1,   5,   5,   5,   1]
list2 = [val, val, val, val, val, val] 

indices = [i for i in range(1, len(list1)) if 5 == list1[i-1] == list1[i]]

for i in reversed(indices):
    list1.insert(i, 1)
    list2.insert(i, Nval)

print(list1) # [5, 1, 5, 1, 5, 1, 5, 1]
print(list2) # [val, val, val, Nval, val, Nval, val, val]
Olivier Melançon
  • 21,584
  • 4
  • 41
  • 73
0

You can use itertools.groupby:

import itertools
list1 = [5, 1, 5, 5, 5, 1]
copied = iter(['val' for _ in list1])
grouped = [[a, list(b)] for a, b in itertools.groupby(list1)]
new_result = [list(b) if a != 5 else [[5, 1] if c < len(b) - 1 else [5] for c, _ in enumerate(b)] for a, b in grouped]
final_result = [[i] if not isinstance(i, list) else i for b in new_result for i in b]
new_copied = [[next(copied)] if len(i) == 1 else [next(copied), 'Nval'] for i in final_result]
list2, list2_copied = list(itertools.chain(*final_result)), list(itertools.chain(*new_copied))

Output:

[5, 1, 5, 1, 5, 1, 5, 1]
['val', 'val', 'val', 'Nval', 'val', 'Nval', 'val', 'val']
Ajax1234
  • 69,937
  • 8
  • 61
  • 102
0
list1 = [5,1,5,5,5,1,5,5,1,5,5,5,5]
list2 = []

templist = []

for idx,val in enumerate(list1):
    if (idx+1) <= (len(list1)-1):
        if list1[idx+1] == 5 and list1[idx] == 5:
            templist.append(val)
            templist.append(1)
            list2.append(val)
            list2.append(42)
        else:
            templist.append(val)
            list2.append(val)

Gives me as output:

templist [5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1]
list2 [5, 1, 5, 42, 5, 42, 5, 1, 5, 42, 5, 1, 5, 42, 5, 42, 5, 42]

And to finish off: list1 = templist

Janko
  • 137
  • 2
  • 14
0

One-line solution based on zip and reduce:

from functools import reduce

new_val = 10  # value to use for list2 (Nval)
new_list1 = []
new_list2 = []
reduce(lambda x, y: ((y[0] == 5 and x == 5) and (new_list1.append(1) or new_list2.append(new_val))) or
                     new_list1.append(y[0]) or new_list2.append(y[1]) or y[0],
         zip(list1, list2), (None, new_list1, new_list2))
PieCot
  • 3,564
  • 1
  • 12
  • 20