Code › codeit-ai-sprint

Python Dictionaries, Views, and String Indexing

A Codeit AI Engineer Sprint pre-course note on dictionary view objects, string immutability, and Python indexing

Today I finished the third and final Python course in the pre-course sequence. This one covered dictionaries, vocabulary-book style examples, lists and strings, aliasing, and small exercises like reversing a dictionary and counting votes. Most of it was still basic Python, but the way Python handles dictionaries and strings stood out more this time.

The first point was that strings can be indexed, but they cannot be changed through that index. word[0] gives me the first character, but word[0] = "H" raises an error. At first, it is easy to think this is because the value is a literal, but the more accurate reason is that Python strings are immutable. Once a string object is created, its contents cannot be modified in place.

word = "hello"
print(word[0])  # h

# word[0] = "H"  # TypeError
word = "H" + word[1:]
print(word)  # Hello

In C++, std::string can be changed by index. In TypeScript and JavaScript, strings are immutable like Python strings, so assigning to text[0] does not actually rewrite the string. The indexing syntax may look similar across languages, but whether the value is a mutable container or an immutable object changes how I should work with it.

The second point was the return type of keys(), values(), and items() on dictionaries. I guessed they probably would not create a fresh list every time, and that was right. They return dictionary view objects: dict_keys, dict_values, and dict_items. These objects look at the original dictionary and reflect changes to it.

scores = {"kim": 90, "lee": 85}
keys = scores.keys()
items = scores.items()

print(keys)          # dict_keys(['kim', 'lee'])
print(list(items))   # [('kim', 90), ('lee', 85)]

scores["park"] = 100
print(keys)          # dict_keys(['kim', 'lee', 'park'])

That design makes sense for both memory and meaning. If a dictionary has many keys, creating a new list every time keys() is called would add unnecessary copying. A view object is lighter because it does not own a separate copy of the data, and it stays connected to the dictionary. The feeling is closer to a non-owning view or iterator in C++ than to TypeScript’s Object.keys(), which returns a new array.

A dictionary view is still not the same as a list. It can be used in a loop, but it cannot be indexed directly. If I want list behavior, I need to convert it explicitly.

scores = {"kim": 90, "lee": 85}

for name in scores.keys():
    print(name)

names = list(scores.keys())
print(names[0])

Negative indexing is another small Python feature that feels nice when I come back to it. In a list or string, -1 means the last element. In many other languages, I usually reach for something like length - 1, but Python gives this directly in the indexing syntax.

letters = ["a", "b", "c"]
print(letters[-1])  # c
print(letters[-2])  # b

With this course, I have finished all three Python courses in the Codeit AI Engineer Sprint pre-course. A lot of the material was familiar, but it was still useful to revisit the small differences instead of only relying on memory. Python is going to keep showing up in AI and data work, so I would rather keep these basics clean now.

Since the available pre-course material also includes some free machine learning lectures, I may listen to a few of those next. The main course is not far away, but the Python foundation feels a little more settled now.