3

I am looking for a more efficient way (if available) to split a list into two sub-lists. An example of the original list:

full_list = ['t1', 't2', 't3', 't4', 't5', 'v1', 'v2']

NOTE: In general the original list contains an arbitrary amount of elements that are mixed together. The 't1' ... 't5' just serve to indicate elements of the first sub-list:

t_sub_list = ['t1', 't2', 't3', 't4', 't5']

This sub-list is a given.

I would like to most efficiently generate the second sub-list:

v_sub_list = ['v1', 'v2']

The solutions that come to my mind are:

v_sub_list_A = [list_element for list_element in full_list if list_element not in t_sub_list]
v_sub_list_B = list(set(full_list) - set(t_sub_list))

The question I have is - is there any more efficient way of doing this? Or at least any package that would allow to achieve the result in a more code-readable fashion?

glamredhel
  • 336
  • 3
  • 12

3 Answers3

7

As stated, it's even easier than that. Since all of the first list elements are on the left, you need only deal with finding the break point. Use the list length.

full_list = ['t1', 't2', 't3', 't4', 't5', 'v1', 'v2']
t_sub_list = ['t1', 't2', 't3', 't4', 't5']

left_size = len(t_sub_list)
v_sub_list = full_list[left_size:]

This yields the result you described.

Prune
  • 76,765
  • 14
  • 60
  • 81
  • as in the other answer posted - this will not solve the general case - where the list elements are randomly mixed. I have emphasized it now in the question, since it was overlooked. – glamredhel Apr 02 '20 at 08:03
0

you can compare the t_sub_list with all your full_list so it will split the v_sub_list.....

full_list = ['t1', 't2', 't3', 't4', 't5', 'v1', 'v2']
t_sub_list= ['t1', 't2', 't3', 't4', 't5']
v_sub_list=[]

for i in full_list:                 
    if i in t_sub_list:
        pass
    if i not in t_sub_list:
        v_sub_list.append(i)
print(v_sub_list)

the output will be.....

['v1', 'v2']
Lakshmi Ram
  • 11
  • 1
  • 7
  • this won't work in my case, since the list elements are mixed together randomly. I only emphasized the splitting into two sub-lists. Hence slicing won't solve it. – glamredhel Apr 02 '20 at 08:00
  • @glamredhel-I am edited the code ....now you can check – Lakshmi Ram Apr 02 '20 at 10:49
  • A much shorter version that does this is already posted in the question: t_A = [list_element for list_element in full_list if list_element not in t_sub_list] Please read carefully. – glamredhel Apr 02 '20 at 11:28
0

since t_sub_list it is not always at the beginning of full_list and your elements are unique you can use:

full_list = ['t1', 't2', 't3', 't4', 't5', 'v1', 'v2']
t_sub_list = ['t1', 't2', 't3', 't4', 't5']

start_index = full_list.index(t_sub_list[0])
t_size = len(t_sub_list)

v_sub_list = full_list[0:start_index] + full_list[start_index + t_size:]
# ['v1', 'v2']

you are searching the index for the first item from t_sub_list and then you calculate the size of t_sub_list in order to take all the elements around your t_sub_list


if in your t_sub_list are random numbers form full_list you can use a list comprehension:

t_sub_lis = set(t_sub_lis) # will make search O(1)
v_sub_list = [e for e in full_list if e not in t_sub_list]
kederrac
  • 16,819
  • 6
  • 32
  • 55
  • Please read the question carefully. 1. The elements of the t_sub_list are not necessarily a consecutive block. They are randomly mixed with the other elements. 2. The list comprehension solution and the set difference solution I have posted in the question itself - I am asking if there are any other, more efficient / more elegant solutions than those two. – glamredhel Apr 02 '20 at 11:30
  • @glamredhel My last solution is more efficient since I use a set in the list comprehension – kederrac Apr 02 '20 at 11:36