If you have many queries and/or a dynamic list of lists, then you are better off making a map. Specifically a value:set map. Where you map the value to a set of indices (sub-lists) that contain that value. Though this works best if the list doesn't change.
Example for [[1,2,3,4],[5,6,7,8,9,10], [11,12,13], [1,2,3,4,5,6,7,8,9,10,11,12,13]
:
# Code for populating the map
map = collections.defaultdict(set)
index = 0
for i,v in enumerate(l):
for _ in v:
map[index].add(i)
index += 1
# Result:
map = {
1: {0,3},
2: {0,3},
3: {0,3},
4: {0,3},
5: {1,3},
6: {1,3},
7: {1,3},
8: {1,3},
9: {1,3},
10:{1,3},
11:{2,3},
12:{2,3},
13:{2,3}
}
You can also treat the sub-lists as intervals (covering a range of indices) and allowing for O(log N) look up and O(log N) add/remove sublist/element by building an interval tree. It takes O(L log L) to build the interval tree where L is the number of sublists.