-1

I have the following list:

['F1', [10, 'r'], 'F2', 'F5', [15, 'w'] 'F3', [14, 'r'], 'F4']

I want the index of the list [15, 'w'] using the value 15.
What would be the most efficient way of obtaining the index value? (answer should be 4)

I tried using lambda x: x[0] inside the python .index() function but could not figure out anything of value. I do not want to use loops and if statements. Is there a way to efficiently carry out this task using python's in-built functionalities?

The first value of every list will be unique for all lists inside the main list.

Edit:
By saying "I do not want to use loops" I meant nested loops and if-statements which increase the complexity of the solution, since I will be working with very large lists in many places of the code. So one loop would be fine as long as the complexity isn't greatly increased.

ishiz
  • 61
  • 5

2 Answers2

1

Loops can't be avoided here. Your claim "I do not want to use loops" should be replaced with "I want to push all looping down to C level". But, unfortunally, this is a bad idea, because your data types are not balanced. Although, I will demonstrate my vectorized (C-level) approach:

def cindex(x):
    x = np.array(x, dtype='O') #forcing all the items to be 'object' type
    f = np.vectorize(lambda x: isinstance(x, list)) #convert pyfunc to numpy accepted func
    list_idx, = np.where(f(x)) #identify indices of x items that are lists
    y = np.array(x[f(x)].tolist()) #filter y to contain only lists
    equality_idx, = np.where(y[:,0]=='15') #identify indices of y where first item is '15'
    return np.arange(len(x))[list_idx][equality_idx]

Now let's compare this with @AlexisG solution which I think is standard in this case. It took about 2ms to run it with input that has 8000 items (and only last item has been a proper one).

  • Forcing all the items to be 'object' type costs 70% of this time.
  • Conversion of pyfunc to vectorized func is costless
  • Applying this function cell-wise takes >100% of this time, this is slow.
  • Making list of items of list type is costless but it takes about 200% of this time to convert back to numpy array [[10, 'r'], [15, 'w'], ...
  • All the futher operations such as finding items that starts with 15 and extracting indices can be interpreted as costless because it's C-level already.

So all in all, algorithm is 3-4 times slower so avoid numpy arrays when your data types are unbalanced.

mathfux
  • 5,759
  • 1
  • 14
  • 34
0

I know there are loops. But I wanted to practice list comprehension with your example.

list_ = ['F1', [10, 'r'], 'F2', 'F5', [15, 'w'], 'F3', [14, 'r'], 'F4']
index = next((key for key, value in enumerate(list_) if type(value) == list for i_ in value if i_ == 15), None)
AlexisG
  • 2,476
  • 3
  • 11
  • 25