0

I have seen similar questions to mine, but nothing I researched really fixed my issue.
So, basically I want to split a list, in order to remove some items and concatenate it back. Those items correspond to indexes that are given by a list of tuples.

import numpy as np
arr = ['x','y','z','a','b','c','d','e','f','g',2,3,4]
indices = [(2,4),(7,9)] #INDEXES THAT NEED TO BE CUT OUT
print ([list1[0:s] +list1[s+1:e] for s,e in indices])
#Returns: [['x', 'y', 'z', 'a'], ['x', 'y', 'z', 'a', 'b', 'c', 'd', 'e', 'f']]

This code I have, which I got from one of the answers from this post nearly does what I need, but I tried to adapt it to loop over the first index of indices once but instead it does twice and it doesn't include the rest of the list.

I want my final list to split from zero index to the first item on first tuple and so on, using a for loop or some iterator.
Something like this,

`final_arr = arr[0:indices[0][0]] + arr[indices[0][1]:indices[1][0]] + arr[indices[1][1]:]<br/>
#Returns: [['x','y','a','b','c','f','g',2,3,4]]`

If someone could do it using for loops, it would be easier for me to see how you understand the problem, then after I can try to adapt to using shorter code.

Angel Lira
  • 293
  • 3
  • 12

4 Answers4

2

Sort the indices using sorted and del the slices. You need reverse=True otherwise the indices of the later slices are incorrect.

for x, y in sorted(indices, reverse=True):
    del(arr[x:y])

print(arr)

>>> ['x', 'y', 'b', 'c', 'd', 'g', 2, 3, 4]

This is the same result as you get with

print(arr[0:indices[0][0]] + arr[indices[0][1]:indices[1][0]] + arr[indices[1][1]:])

>>> ['x', 'y', 'b', 'c', 'd', 'g', 2, 3, 4]
ScootCork
  • 3,411
  • 12
  • 22
1

Like this:

import numpy as np
arr = ['x','y','z','a','b','c','d','e','f','g',2,3,4]
indices = [(2,4),(7,9)] #INDEXES THAT NEED TO BE CUT OUT
print ([v for t in indices for i,v in enumerate(arr) if i not in range(t[0],t[1])])

Output:

['x', 'y', 'z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 2, 3, 4, 'x', 'y', 'z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 2, 3, 4]
Red
  • 26,798
  • 7
  • 36
  • 58
1

arr = ['x','y','z','a','b','c','d','e','f','g',2,3,4]
indices = [(2,4),(7,9)] #INDEXES THAT NEED TO BE CUT OUT

import itertools

ignore = set(itertools.chain.from_iterable(map(lambda i: range(*i), indices)))
out = [c for idx, c in enumerate(arr) if idx not in ignore]

print(out)
print(arr[0:indices[0][0]] + arr[indices[0][1]:indices[1][0]] + arr[indices[1][1]:])

Output,

['x', 'y', 'b', 'c', 'd', 'g', 2, 3, 4]
['x', 'y', 'b', 'c', 'd', 'g', 2, 3, 4]
blakev
  • 4,154
  • 2
  • 32
  • 52
  • Hi @blakev could you explain to me what this itertools.chain.from_iterable really does? I think piece of code might work. But I am new to Python and those fancy methods are hard to comprehend! – Angel Lira Jun 26 '20 at 18:22
  • `itertools.chain.from_iterable` takes a list of lists and compresses it into a "flat" list. [Python documentation](https://docs.python.org/3/library/itertools.html#itertools.chain.from_iterable). – blakev Jun 26 '20 at 18:34
0

1- If you can remove the list items:
I using the example for JimithyPicker. I change the index list (removed items), because always that one index was removed the size of list change.

arr = ['x','y','z','a','b','c','d','e','f','g',2,3,4]
indices = [2,5,5] #INDEXES THAT NEED TO BE CUT OUT

for index in indices:
    arr.pop(index)

final_arr = [arr]
print(final_arr)

Output:

[['x', 'y', 'a', 'b', 'c', 'f', 'g', 2, 3, 4]]

2- If you can't remove items:
In this case is necessary change the second index! The number doesn't match with output that you want.
The indices = [(2,4),(7,9)] has the output: ['x', 'y', 'a', 'b', 'c', 'd', 'f', 'g', 2, 3, 4]

arr = ['x','y','z','a','b','c','d','e','f','g',2,3,4]
indices = [(2,4),(6,9)] #INDEXES THAT NEED TO BE CUT OUT

final_arr = arr[0:indices[0][0]] + arr[indices[0][1]-1:indices[1][0]] + arr[indices[1][1]-1:]
print(final_arr)

Output:

['x','y','a','b','c','f','g',2,3,4]