qingPython ctypes: Calling C Libraries from Python tags: python, programming, tutorial,...
tags: python, programming, tutorial, advanced
tags: python, programming, tutorial, advanced
tags: python, programming, tutorial, advanced
tags: python, programming, tutorial, advanced
tags: python, programming, tutorial, advanced
tags: python, performance, tutorial, programming
tags: python, performance, tutorial, programming
tags: python, performance, tutorial, programming
tags: python, search, tutorial, beginners
tags: python, search, tutorial, beginners
You’ve probably typed a query into Google and wondered, “How does it actually find that exact article in a blink?” Spoiler: it’s not magic—it’s math, data structures, and a little bit of Python. And guess what? You can build your own search engine today, from scratch, with just a few hundred lines of code. No cloud APIs, no paid subscriptions—just pure, educational Python.
Let’s ditch the complexity and build something simple, functional, and surprisingly powerful: a text-based search engine that indexes local documents and lets you query them instantly.
Before we dive into code, let’s be clear: you don’t need to build a search engine to get results. But if you’re a developer, data scientist, or curious learner, building one teaches you:
This isn’t just theory. You’ll walk away with a working tool you can use to search your own notes, code snippets, or documentation folder.
Every search engine, from the simplest script to massive distributed systems, follows the same core pipeline:
We’ll implement all five steps in Python, using only built-in libraries. No external dependencies.
Start by creating a folder called docs and dropping in a few .txt files. For example:
docs/
python_basics.txt
machine_learning.txt
web_development.txt
Each file should contain plain text you’d like to search. In our case, we’ll use sample content about programming topics.
Raw text is messy. Words have punctuation, mixed casing, and stop words like “the” or “and” that add noise. We’ll clean it up:
Here’s a helper function to do that:
import re
from collections import defaultdict
def tokenize(text):
# Convert to lowercase and remove non-alphanumeric characters
text = text.lower()
text = re.sub(r'[^\w\s]', '', text)
# Split into words
return text.split()
This function turns "Hello, world!" into ['hello', 'world']. Clean, consistent, and ready for indexing.
The inverted index is the heart of our search engine. Instead of storing “which words are in document A,” we store “which documents contain word X.”
We’ll use a defaultdict where each key is a word and the value is a list of document filenames.
def build_index(doc_folder):
import os
index = defaultdict(list)
for filename in os.listdir(doc_folder):
if filename.endswith('.txt'):
filepath = os.path.join(doc_folder, filename)
with open(filepath, 'r', encoding='utf-8') as f:
text = f.read()
tokens = tokenize(text)
for token in tokens:
index[token].append(filename)
return index
Now, if you search for "python", the index instantly tells you all files containing that word.
With the index built, searching is straightforward:
We’ll use AND logic for stricter matches:
def search(query, index):
tokens = tokenize(query)
results = set(index[tokens[0]])
for token in tokens[1:]:
if token in index:
results &= set(index[token])
else:
return [] # No document contains this word
return list(results)
Try it out:
if __name__ == "__main__":
index = build_index("docs")
query = input("What do you want to search? ")
matches = search(query, index)
if matches:
print(f"Found {len(matches)} document(s):")
for doc in matches:
print(f" - {doc}")
else:
print("No matches found. Try a different query.")
Run this script, type a query like python basics, and watch it return matching files. You’ve just built a working search engine.
Right now, every matching document is returned equally. But in real search engines, ranking matters. You can score documents by:
For a quick upgrade, add term frequency scoring:
def search_with_ranking(query, index, doc_folder):
tokens = tokenize(query)
scores = defaultdict(int)
# Get candidate documents
candidates = set()
for token in tokens:
if token in index:
candidates |= set(index[token])
# Score each candidate
for doc in candidates:
filepath = os.path.join(doc_folder, doc)
with open(filepath, 'r', encoding='utf-8') as f:
text = f.read()
tokens_in_doc = tokenize(text)
for token in tokens:
scores[doc] += tokens_in_doc.count(token)
# Sort by score
ranked = sorted(scores.items(), key=lambda x: x[1], reverse=True)
return [doc for doc, _ in ranked]
Now, documents with more occurrences of your query terms appear first. That’s how relevance is born.
You don’t need to wait for a perfect setup. Here’s how to use this today:
.txt or .md learning notes into docs and query them.The code is modular. Swap out the tokenizer, add stemming, or integrate with SQLite for persistence. You’ve got the foundation.
This tiny engine mirrors the architecture of giants like Google. They just scale it: distributed indexes, real-time updates, machine-learned ranking, and billions of documents. But the core idea—map words to documents, then match queries—is the same.
By building this, you’ve touched the same principles that power modern search. And that’s worth more than just a working script.
Try these next steps:
sentence-transformers).Drop your version in the comments, or fork the code and share what you built. The best way to learn is to build, break, and rebuild.
You didn’t just read about search engines—you built one. Now go search something.
If you found this helpful, consider buying me a coffee ☕ — it keeps these articles coming!
Also check out my AI tools collection: AI 次元世界 — free AI tools for developers.