Python Find an Item in a List: Return the Match or None
A search function can return the value it found, not just True or False. When nothing matches, it returns None so the caller can tell "found" from "not found".
Read Stopping a Search with return first. The examples also use range() and unpacking.
None is Python's value for "nothing here". A function that ends without a return also gives back None.
Return the matching item
Return the item itself inside the loop. After the loop, return None.
def find_long_word(words, length):
for word in words:
if len(word) >= length:
return word
return None
print(find_long_word(["cat", "zebra", "otter"], 5))
print(find_long_word(["cat", "dog"], 5))
The first call prints zebra, the first long enough word. otter is never checked. The second call finds nothing and prints None.
Check for None before using the result
The caller must handle the "not found" case. is None asks "is this the None value?". Use it rather than == None.
def find_long_word(words, length):
for word in words:
if len(word) >= length:
return word
return None
word = find_long_word(["cat", "dog"], 5)
if word is None:
print("No long word")
else:
print(word.upper())
Without the check, word.upper() would crash with AttributeError, because None has no upper() method.
Return a position instead of the item
Sometimes you need where the match is. Loop over range(len(...)) and return the index.
def first_index_over(scores, limit):
for index in range(len(scores)):
if scores[index] > limit:
return index
return None
print(first_index_over([40, 75, 90], 70))
print(first_index_over([40, 55], 70))
The first call prints 1: scores[1] is 75. The second prints None.
Watch out: a found value can look false
Index 0 and empty text "" are real answers, but they are falsy. if result: treats them like "not found".
def first_index_over(scores, limit):
for index in range(len(scores)):
if scores[index] > limit:
return index
return None
result = first_index_over([90, 40], 70)
if result:
print("found at", result)
else:
print("not found") # wrong: the match is at index 0
if result is not None:
print("found at", result)
The first if prints not found, which is wrong. is not None gets it right and prints found at 0.
Note: Returning None is the simplest "not found" signal. Real code sometimes raises an exception instead, or uses a built-in such as list.index() or str.find(). These examples leave out type hints such as str | None.
See also: Truthy and falsy values, Optional and Union types.
Your turn
Finish find_price(items, name). Each item is a [name, price] pair. Loop with for item_name, price in items:. Return the price of the first item called name, or None if there is none. Then print the result for "pear", and "Not sold" for "kiwi".
def find_price(items, name):
# loop over the pairs, return the matching price,
# and return None after the loop
pass
stock = [["apple", 3], ["pear", 0], ["plum", 5]]
# print find_price(stock, "pear"),
# then print "Not sold" if find_price(stock, "kiwi") is None
Expected output
0
Not sold