### Question :

Let’s assume I’m creating a simple class to work similar to a C-style struct, to just hold data elements. I’m trying to figure out how to search a list of objects for objects with an attribute equaling a certain value. Below is a trivial example to illustrate what I’m trying to do.

For instance:

```
class Data:
pass
myList = []
for i in range(20):
data = Data()
data.n = i
data.n_squared = i * i
myList.append(data)
```

How would I go about searching the myList list to determine if it contains an element with n == 5?

I’ve been Googling and searching the Python docs, and I think I might be able to do this with a list comprehension, but I’m not sure. I might add that I’m having to use Python 2.4.3 by the way, so any new gee-whiz 2.6 or 3.x features aren’t available to me.

##
Answer #1:

You can get a list of *all* matching elements with a list comprehension:

```
[x for x in myList if x.n == 30] # list of all elements with .n==30
```

If you simply want to determine if the list contains *any* element that matches and do it (relatively) efficiently, you can do

```
def contains(list, filter):
for x in list:
if filter(x):
return True
return False
if contains(myList, lambda x: x.n == 3) # True if any element has .n==3
# do stuff
```

##
Answer #2:

**Simple, Elegant, and Powerful:**

A generator expression in conjuction with a builtin… (python 2.5+)

```
any(x for x in mylist if x.n == 10)
```

Uses the Python `any()`

builtin, which is defined as follows:

any(iterable)`->`

Return True if any element of the iterable is true. Equivalent to:

```
def any(iterable):
for element in iterable:
if element:
return True
return False
```

##
Answer #3:

Just for completeness, let’s not forget the Simplest Thing That Could Possibly Work:

```
for i in list:
if i.n == 5:
# do something with it
print "YAY! Found one!"
```

##
Answer #4:

```
[x for x in myList if x.n == 30] # list of all matches
[x.n_squared for x in myList if x.n == 30] # property of matches
any(x.n == 30 for x in myList) # if there is any matches
[i for i,x in enumerate(myList) if x.n == 30] # indices of all matches
def first(iterable, default=None):
for item in iterable:
return item
return default
first(x for x in myList if x.n == 30) # the first match, if any
```

##
Answer #5:

```
filter(lambda x: x.n == 5, myList)
```

##
Answer #6:

You can use `in`

to look for an item in a collection, and a list comprehension to extract the field you are interested in. This (works for lists, sets, tuples, and anything that defines `__contains__`

or `__getitem__`

).

```
if 5 in [data.n for data in myList]:
print "Found it"
```

See also:

##
Answer #7:

You should add a `__eq__`

and a `__hash__`

method to your `Data`

class, it could check if the `__dict__`

attributes are equal (same properties) and then if their values are equal, too.

If you did that, you can use

```
test = Data()
test.n = 5
found = test in myList
```

The `in`

keyword checks if `test`

is in `myList`

.

If you only want to a a `n`

property in `Data`

you could use:

```
class Data(object):
__slots__ = ['n']
def __init__(self, n):
self.n = n
def __eq__(self, other):
if not isinstance(other, Data):
return False
if self.n != other.n:
return False
return True
def __hash__(self):
return self.n
myList = [ Data(1), Data(2), Data(3) ]
Data(2) in myList #==> True
Data(5) in myList #==> False
```

##
Answer #8:

Consider using a dictionary:

```
myDict = {}
for i in range(20):
myDict[i] = i * i
print(5 in myDict)
```