Reputation: 55
I have a list L of 4-length list
L = [[1,2,12,13],[2,3,13,14],...]
and two integers a and b which appear many times in the sublists. What I want is to find the index of the sublists in L which contain a AND b.
I wrote a little code
l=[]
for i in range(len(L)):
if L[i][0]==a or L[i][1]==a or L[i][2]==a or L[i][3]==a:
l.append([i] + L[i]) # I put the index in the first position.
# Now l is a list of 5-length lists.
# I do the same loop on that list.
r=[]
for i in range(len(l)):
if l[i][1]==b or l[i][2]==b or l[i][3]==b or l[i][4]==b:
r.append(i)
The index I am looking for are in the list r. However I am pretty sure there is another way to do it in Python since I barely know this language. Maybe if my variable L is something else than a list of lists it would be easier/faster, because I will call this procedure a lot in my main program. (len(L) is around 3000)
By the way I know that the number of index is between one and four included, so I could put some break but I don't know if it will be faster.
---------------- EDIT 1 ----------------
Change "a or b (or is inclusive)" to "a AND b" in the second sentence. I wrote a mistake about my goal.
Upvotes: 0
Views: 103
Reputation: 29307
Try with
for index, item in enumerate(L):
if a in item or b in item:
r.append(index)
Upvotes: 0
Reputation: 2511
This kind of thing is what list comprehension is made for.
If you really want inclusive or -- then this is the list you want. In your code, currently, you've giving and.
result = [a_tuple for a_tuple in L if a in a_tuple or b in a_tuple]
Upvotes: 0
Reputation: 2249
You can do this:
r = [i for i,x in enumerate(L) if any(y in x for y in (a,b))]
enumerate will give you both indices and values in your list comprehension, and the any statement will tell you if either a or b are in x, which is a sublist in L
Upvotes: 2
Reputation: 2617
Use any()
to test the sublists:
if any(a in subl for subl in L):
This tests each subl
but exits the generator expression loop early if a match is found.
This does not, however, return the specific sublist that matched. You could use next()
with a generator expression to find the first match:
matched = next((subl for subl in L if a in subl), None)
if matched is not None:
matched[1] += 1
where None
is a default returned if the generator expression raises a StopIteration
exception, or you can omit the default and use exception handling instead:
try:
matched = next(subl for subl in L if a in subl)
matched[1] += 1
except StopIteration:
pass # no match found
Upvotes: 0