Exploring List Queries

Introduction: Asking Questions About a List

Welcome back to Building and Modifying Lists in Python. We have created lists, grown and shrank them, then rewrote and reordered their contents. This lesson takes a step back and asks questions instead.

Four questions, to be precise:

  1. Is this value here?
  2. How many times does it appear?
  3. Where is it?
  4. How do I put two lists together?

Our running example is a short list of colors, and the repeated "blue" is there on purpose: It is what will make counting and locating genuinely interesting. None of the tools ahead modify the list; they only look at it or produce something new from it.

Membership Testing with in and not in

The first question is the simplest: Is a value present? We already know the operator from earlier work with strings, and it works on lists too:

Python
colors = ["red", "blue", "green", "blue"]

# Membership tests produce Boolean values
print("Has blue:", "blue" in colors)
print("Missing yellow:", "yellow" not in colors)

There is one important difference from strings. With text, in could match a piece of the string, so "re" in "red" was True. With a list, in compares against whole items, so "re" in colors is False even though "red" sits right there; the item must match completely. Both expressions evaluate to a Boolean (True or False), which is why we can print them directly. not in is Python’s direct membership form for absence and is equivalent to not (value in collection); the not in form usually reads more clearly.

text
Has blue: True
Missing yellow: True

Counting Occurrences with count()

A yes-or-no answer is often not enough. The count() method upgrades it to a number:

Python
# count() reports how many times a value appears
print("Number of blue items:", colors.count("blue"))

count() walks through the list and returns an integer: the number of items equal to the value we passed. Two details are worth holding onto:

  • It counts exact matches only, following the same whole-item rule as in.
  • A value that never appears returns 0, not an error, so colors.count("yellow") is a perfectly safe call.

Compare this with remove() from earlier, which also searches for a value: remove() edits the list and returns None, while count() leaves the list alone and hands back a value we can print or store.

text
Number of blue items: 2

Locating a Value with index()

Knowing that "blue" appears twice raises the next question: where? The index() method answers with a position:

Python
# index() reports the position of the first matching value
print(colors.index("blue"))   # 1, not 3

Our list is ["red", "blue", "green", "blue"], so "blue" appears at indices 1 and 3. index() returns 1 and stops there: It always reports the first match and ignores every later one.

List indices showing that index returns the first matching blue item

Now the catch, and it is a big one. When working with strings, find() returned -1 for text it could not locate. Lists have no such courtesy: colors.index("yellow") raises a ValueError and stops the program. That difference means missing values need to be handled deliberately, which is exactly what the next section is about.

Guarding index() with a Membership Check

Since a missing value crashes index(), a clear beginner-friendly pattern is to check first and search second:

Python
target = "green"
if target in colors:
    print("Green is at index:", colors.index(target))
else:
    print("Green was not found.")

The in test acts as a gate: colors.index(target) runs only on the branch where we already know the value exists, so the ValueError can never happen. Since "green" is in our list, the if branch runs and reports index 2. Change target to "yellow", and the program calmly prints the else message instead of crashing.

This approach may scan the list twice when the target is present: once for in and again for index(). After learning exception handling, another option is to call index() once inside a try block and handle ValueError with except. For now, the membership check is a clear way to keep the lookup safe.

text
Green is at index: 2

Combining Lists with +

Our last question is about joining. Suppose we keep colors in two themed lists and want one list holding both:

Python
# The + operator creates a new combined list
warm_colors = ["red", "orange"]
cool_colors = ["blue", "green"]
all_colors = warm_colors + cool_colors

print("Combined:", all_colors)

The + operator builds a brand-new outer list: every item of the left list first, in order, followed by every item of the right list. This mirrors string concatenation from the earlier course, where "Hello" + " there" produced a new string. Because a new outer list is created, we must capture it in a variable; warm_colors + cool_colors on its own line would compute the result and throw it away. One restriction: Both sides must be lists, so ["a"] + "b" raises a TypeError.

Warm and cool color lists combining into a new list in order

The newly combined list contains the warm colors first and the cool colors second, so it displays in this order:

text
Combined: ['red', 'orange', 'blue', 'green']

+ Leaves the Originals Alone

That word "new" deserves proof, so let us print the two source lists after combining them:

Python
print("Warm colors unchanged:", warm_colors)
print("Cool colors unchanged:", cool_colors)

Both still hold exactly two items each. all_colors is a separate outer list; joining did not pour one list into the other. If the source lists held mutable nested items such as inner lists, those inner items would still be shared with the combined list. Copying nested data independently is a later topic. This is different from extend() in Unit 2, which grows the list it is called on:

ToolChanges original?Returns
a + bNo, both untouchedA new combined list
a.extend(b)Yes, a growsNone

This is the theme that has followed us throughout the course: in-place tools versus new-object tools. It determines one small thing on every line we write: whether we print the variable afterward or capture the returned value.

text
Warm colors unchanged: ['red', 'orange']
Cool colors unchanged: ['blue', 'green']

Bringing It Together

The complete script below uses the four list-query tools: membership testing, counting, guarded locating, and combining.

Python
colors = ["red", "blue", "green", "blue"]

print("Has blue:", "blue" in colors)              # Boolean
print("Missing yellow:", "yellow" not in colors)  # Boolean
print("Number of blue items:", colors.count("blue"))   # integer

target = "green"
if target in colors:                              # guard the lookup
    print("Green is at index:", colors.index(target))
else:
    print("Green was not found.")

warm_colors = ["red", "orange"]
cool_colors = ["blue", "green"]
all_colors = warm_colors + cool_colors            # new list

print("Combined:", all_colors)
print("Warm colors unchanged:", warm_colors)
print("Cool colors unchanged:", cool_colors)

These results show both the questions answered by the tools and the fact that combining leaves its source lists unchanged:

text
Has blue: True
Missing yellow: True
Number of blue items: 2
Green is at index: 2
Combined: ['red', 'orange', 'blue', 'green']
Warm colors unchanged: ['red', 'orange']
Cool colors unchanged: ['blue', 'green']

Conclusion and Next Steps

In this lesson, you used membership tests to check whether values appear in a list, count() to measure repeated values, and index() with a membership guard to locate values safely. You also combined lists with + while keeping the original lists unchanged.

The most important distinction is between tools that inspect a list and tools that create or modify one. The membership operators, count(), and guarded index() inspect the existing list. The + operator creates a new combined list, while extend() from earlier changes an existing list.

Look at the arc we have completed: creating and accessing lists, adding and removing items, editing and ordering them, and now checking and combining them. That is a full working toolkit, and congratulations on reaching the end of Building and Modifying Lists in Python. These same habits also transfer naturally to dictionaries and key-value data.

Sign up

Join the 1M+ learners on CodeSignal

Be a part of our community of 1M+ users who develop and demonstrate their skills on CodeSignal