How to check if an element exists in a list of lists in Python?
I want to check if (for example) elem3 is in any of the lists, and if it is, go into that list. (really I have a list of things I need to check, so it’s a list that probably contains elem3 , elem5 , elem7 . etc)
just return it (i’m planning on evaluating the other elements in the list). It’s as if I’m using the elem3 as a key into the list. unfortunately the file is not set up as a dictionary.
@karthikr: I don’t believe that answer applies to this question (it returns a boolean instead of returning the matching list, and can’t be easily adapted to return the list).
4 Answers 4
the shortest way is to use list comprehensions and list comprehensions sometimes are more faster than simple for loop
list1 = [ ["col1", "col2", "col3"], ["elem1", "elem2", "elem3"], ["elem4", "elem5", "elem6"] ]
your function to «go into that list»:
def do_something(sub_list): print (sub_list)
and the list comprehension that will find your element and call function with list that have it:
[do_something(sub_list) for sub_list in list1 if to_find in sub_list]
Note that this doesn’t actually avoid the nested loops problem of @BobbyRussell’s answer. It just hides it. List comprehensions have essentially the same performance as for loops.
You can do something like this:
def in_list(list_of_lists, item): for list_ in list_of_lists: if item in list_: return list_
Here is a recursive version for the heck of it:
def in_list(list_of_lists, item): if not list_of_lists: return None if item in list_of_lists[0]: return list_of_lists[0] return in_list(list_of_lists[1:], item)
is there any other way to do this than looping over all the lists? i have 2000 lists, each with 8 elements in them.
The complexity of this algorithm is not something you should be worried about. in doesn’t iterate over the list, so you’re just going to iterate over the list_of_lists. It should not be slow at all.
@BobbyRussell » in doesn’t iterate over the list» Yes it does. item in lst is a O(n) operation that iterates over lst until item is found, or lst is exhausted.
@Leistungsabfall If you only want the first occurrence of item in one of the sub-lists, you wouldn’t want a list comprehension here, because you can’t short-circuit it as soon as you find a match. With this answer, you stop as soon as item is found.
I came across a similar problem. I had a list of tuples, with tile numbers:
data = [(0, 0, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 0), (0, 23, 24, 25, 26, 27, 28, 29, 30, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 0), (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21)]
I needed to find out where in the list of tuples a particular tile number is located, so:
to_find = 42 for i in range(len(data)): if to_find in data[i]: print (i, data[i].index(to_find)) break
How to check if all of the following items are in a list?
I found, that there is related question, about how to find if at least one item exists in a list:
How to check if one of the following items is in a list? But what is the best and pythonic way to find whether all items exists in a list? Searching through the docs I found this solution:
>>> l = ['a', 'b', 'c'] >>> all(x in l for x in ['a', 'b']) True >>> all(x in l for x in ['a', 'x']) False
8 Answers 8
Use the equivalent and more clearly-named method, set.issubset . Note that you don’t need to convert the argument to a set; it’ll do that for you if needed.
While I agree with the sentiment, I’m pretty OK with the idea of
@Just: Primarily, because it’s not obvious what
You know the mathematical operator for (non-proper) subset? it basically looks pretty much like a rounded
love this solution. is there a way to get an index location or a list value instead of a bool (True:False)?
I would probably use set in the following manner :
I find it a bit more readable, but it may be over-kill. Sets are particularly useful to compute union/intersection/differences between collections, but it may not be the best option in this situation .
@wok : oh I didn’t know that, but I think the
it’s not really that confusing if you recall the inclusion defines a partial order on any set of sets. It’s actually slightly confusing that
@aaronasterling : mmm, I personnally don’t think too much about «partial order» when I type code :-), but I agree on the fact that using
I ran into a little gotcha here I’d like to mention: If you use this method, you are converting your lists to sets, which means no duplicates. set([‘a’,’a’]).issubset([‘a’]) returns True .
I like these two because they seem the most logical, the latter being shorter and probably fastest (shown here using set literal syntax which has been backported to Python 2.7):
all(x in for x in ['a', 'b']) # or .issubset()
The «all» solution is the quickest when you measure it with timeit(). This should be the accepted answer.
What if your lists contain duplicates like this:
Sets do not contain duplicates. So, the following line returns True.
To count for duplicates, you can use the code:
v1 = sorted(v1) v2 = sorted(v2) def is_subseq(v2, v1): """Check whether v2 is a subsequence of v1.""" it = iter(v1) return all(c in it for c in v2)
So, the following line returns False.
Not OP’s case, but — for anyone who wants to assert intersection in dicts and ended up here due to poor googling (e.g. me) — you need to work with dict.items :
>>> a = >>> b = >>> all(item in a.items() for item in b.items()) True >>> all(item in b.items() for item in a.items()) False
That’s because dict.items returns tuples of key/value pairs, and much like any object in Python, they’re interchangeably comparable
Another solution would be:
l = ['a', 'b', 'c'] potential_subset1 = ['a', 'b'] potential_subset2 = ['a', 'x'] print(False not in [i in l for i in potential_subset1]) # True print(False not in [i in l for i in potential_subset2]) # False
What makes my solution great is that you can write one-liners by putting the lists inline.
An example of how to do this using a lambda expression would be:
issublist = lambda x, y: 0 in [_ in x for _ in y]
Note that using _ as a variable name is confusing in this case. This is because by convention, _ is used for a variable whose value you do not use («throwaway variable»). see: stackoverflow.com/a/5893946/4948719
Short syntax
I discovered a very readable syntax while experimenting on the Python interpreter.
>>> my_list = [1, 2, 3, 4, 5] >>> (6 or 7) in my_list False >>> (2 or 6) in my_list True >>> (2 and 6) in my_list False >>> (2 and 5) in my_list True
List of items to search for
If you have a long list of objects to search for, held in a sub_list variable:
>>> my_list = [1, 2, 3, 4, 5] >>> sub_list = ['x', 'y']
If any (at least one) item is contained in the superset ( or statement):
>>> next((True for item in sub_list if next((True for x in my_list if x == item), False)), False) False >>> sub_list[0] = 3 >>> next((True for item in sub_list if next((True for x in my_list if x == item), False)), False) True
If all items are contained in superset ( and statement), then sub_list is a full subset. Also featuring a bit of De Morgan’s Law:
>>> next((False for item in sub_list if item not in my_list), True) False >>> sub_list[1] = 2 >>> next((False for item in sub_list if item not in my_list), True) True >>> next((True for item in sub_list if next((True for x in my_list if x == item), False)), False) True
Is there a short contains function for lists?
Given a list xs and a value item , how can I check whether xs contains item (i.e., if any of the elements of xs is equal to item )? Is there something like xs.contains(item) ? For performance considerations, see Fastest way to check if a value exists in a list.
Your question implies you’re only interested in list contains item, not list contains sublist? /tuple/ set/ frozenset/.
6 Answers 6
if my_item not in some_list: .
It works fine for lists, tuples, sets and dicts (check keys).
Note that this is an O(n) operation in lists and tuples, but an O(1) operation in sets and dicts.
With a list containing numpy arrays, will this check for numpy instances or values inside the numpy instances?
Beware ! This matches while this is very probably what you did not expect: o=’—skip’; o in («—skip-ias»); # returns True !
@AlexF: That matches because («—skip-ias») is not a tuple, but a string (the parentheses do nothing, just like (1) is just an integer). If you want a 1-tuple, you need to add a comma after the single item: («—skip-ias»,) (or (1,) ).
In addition to what other have said, you may also be interested to know that what in does is to call the list.__contains__ method, that you can define on any class you write and can get extremely handy to use python at his full extent.
>>> class ContainsEverything: def __init__(self): return None def __contains__(self, *elem, **k): return True >>> a = ContainsEverything() >>> 3 in a True >>> a in a True >>> False in a True >>> False not in a False >>>