The str.ljust(width[, fillchar]) method returns a copy of the string left-aligned within a field of the specified width, padding the remaining space on the right with fillchar (defaulting to an ASCII space).
The Columnar Alignment Standard: In terminal user interfaces, log streams, and fixed-width database extracts, textual data (such as names, statuses, and descriptions) is traditionally left-aligned, while numerical figures are right-aligned. If width ≤ len(s), Python returns the original string unaltered without truncation.
The standard CPython signature for str.ljust() is:
str.ljust(width, fillchar=' ', /)
| Parameter | Type | Default | Description |
|---|---|---|---|
width |
int |
Required | Total desired field width. If width is less than or equal to len(s), the original string is returned intact without truncation. |
fillchar |
str |
' ' |
Optional. A single character used to fill the remaining right margin. Passing an empty string or multi-character string raises a TypeError. |
ljust() creates and returns a brand-new string object. The original string remains unmodified.
By default, ljust() places padding spaces on the right side of the text:
label = "CPU Load"
# Pad right margin to 15 characters total
padded = label.ljust(15)
print("Original: ", repr(label))
print("Padded: ", repr(padded))
print("Length: ", len(padded))
Expected Output:
Original: 'CPU Load'
Padded: 'CPU Load '
Length: 15
When the string length meets or exceeds the requested width, Python never truncates the string:
text = "PostgreSQL Database Cluster"
print(text.ljust(10)) # Output: 'PostgreSQL Database Cluster' (len 27)
Passing a custom single character enables dot-leaders, progress bars, and visual delimiters:
item = "Authentication Service"
# Fill right margin with dots '.'
leader = item.ljust(35, ".") + " [ONLINE]"
print(leader)
Expected Output:
Authentication Service............. [ONLINE]
Python's alignment tools provide precise directional formatting across methods and formatted string literals:
| Direction | Method Call | f-String Syntax | Example on "LOG" (w=8, fill='-') |
|---|---|---|---|
| Left Justified | s.ljust(width, fill) |
f"{s:{fill}<{width}}" |
"LOG-----" |
| Right Justified | s.rjust(width, fill) |
f"{s:{fill}>{width}}" |
"-----LOG" |
| Centered | s.center(width, fill) |
f"{s:{fill}^{width}}" |
"--LOG---" |
Combining left-aligned text headers with right-aligned numeric data for readable terminal tables:
def format_inventory_table(rows: list[tuple[str, str, float]]) -> str:
# Column widths: Name (20), Category (15), Price (10)
lines = []
header = "Item Name".ljust(20) + "Category".ljust(15) + "Price".rjust(10)
lines.append(header)
lines.append("-" * 45)
for name, cat, price in rows:
row_str = name.ljust(20) + cat.ljust(15) + f"${price:,.2f}".rjust(10)
lines.append(row_str)
return "\n".join(lines)
inventory = [
("Ergonomic Keyboard", "Peripherals", 129.99),
("USB-C Hub 7-in-1", "Accessories", 49.50),
("UltraSharp 27 Monitor", "Displays", 489.00)
]
print(format_inventory_table(inventory))
Expected Output:
Item Name Category Price
---------------------------------------------
Ergonomic Keyboard Peripherals $129.99
USB-C Hub 7-in-1 Accessories $49.50
UltraSharp 27 Mon...Displays $489.00
Constructing fixed-length character records adhering to legacy enterprise batch file specifications:
def build_flat_record(account_id: str, client_name: str, tx_code: str) -> str:
# Specs: Account ID (10 chars), Client Name (25 chars), Code (5 chars)
f_id = account_id.ljust(10)[:10]
f_name = client_name.ljust(25)[:25]
f_code = tx_code.ljust(5)[:5]
return f"{f_id}{f_name}{f_code}"
rec1 = build_flat_record("ACC-9041", "Alice Smith", "DEP")
rec2 = build_flat_record("ACC-10829", "Robert Johnson Enterprise", "WTH")
print("Record 1:", repr(rec1), "Length:", len(rec1))
print("Record 2:", repr(rec2), "Length:", len(rec2))
Expected Output:
Record 1: 'ACC-9041 Alice Smith DEP ' Length: 40
Record 2: 'ACC-10829 Robert Johnson EnterpriseWTH ' Length: 40
Generating aligned progress and diagnostic summaries:
def format_status_check(task_name: str, status: str, total_width: int = 40) -> str:
# Left-align task with dot fill
padded_task = (task_name + " ").ljust(total_width - len(status) - 1, ".")
return f"{padded_task} {status}"
print(format_status_check("Checking Database Connection", "[OK]"))
print(format_status_check("Validating SSL Certificates", "[OK]"))
print(format_status_check("Redis Cache Warmup", "[FAIL]"))
Expected Output:
Checking Database Connection ...... [OK]
Validating SSL Certificates ....... [OK]
Redis Cache Warmup .............. [FAIL]
Standardizing varying log level tokens (INFO, WARN, ERROR, DEBUG, CRITICAL) so subsequent message timestamps and descriptions align into perfect vertical columns:
def format_log_entry(level: str, timestamp: str, message: str) -> str:
# 8-character field for log level (e.g. CRITICAL takes 8 chars)
lvl_padded = f"[{level.upper()}]".ljust(10)
return f"{lvl_padded} {timestamp} - {message}"
print(format_log_entry("info", "2026-10-13 14:00:00", "Server initialization completed"))
print(format_log_entry("warn", "2026-10-13 14:00:05", "High disk latency detected on volume /dev/sda1"))
print(format_log_entry("error", "2026-10-13 14:00:10", "Connection refused by remote host 10.0.1.20"))
print(format_log_entry("debug", "2026-10-13 14:00:12", "Cache key invalidated for user session 4920"))
Expected Output:
[INFO] 2026-10-13 14:00:00 - Server initialization completed
[WARN] 2026-10-13 14:00:05 - High disk latency detected on volume /dev/sda1
[ERROR] 2026-10-13 14:00:10 - Connection refused by remote host 10.0.1.20
[DEBUG] 2026-10-13 14:00:12 - Cache key invalidated for user session 4920
Passing an empty string or multi-character string to fillchar raises an immediate exception:
# TypeError: The fill character must be exactly one character long
"Name".ljust(10, " ")
# Valid:
"Name".ljust(10, " ")
ljust() never truncates strings that exceed width. If fixed columns must not break text layouts, apply slicing explicitly: val[:width].ljust(width).
Below is a production-grade utility class, ColumnFormatter, demonstrating columnar report generation, dot-leader padding, and automated unit assertions:
class ColumnFormatter:
@staticmethod
def format_column(val: str, col_width: int, max_len: int = 0) -> str:
"""Left-aligns text with optional safety truncation."""
s = str(val)
if max_len > 0 and len(s) > max_len:
s = s[:max_len - 3] + "..."
return s.ljust(col_width)
@staticmethod
def format_dot_leader(title: str, status: str, total_width: int = 40) -> str:
"""Creates dot leaders between label and status."""
prefix = f"{title} "
leader = prefix.ljust(total_width - len(status) - 1, ".")
return f"{leader} {status}"
# ==========================================
# SELF-CHECKING UNIT ASSERTIONS
# ==========================================
formatter = ColumnFormatter()
# 1. Basic space padding
assert "Python".ljust(10) == "Python "
assert "Python".ljust(6) == "Python"
assert "Python".ljust(3) == "Python" # No truncation
# 2. Custom fillchar
assert "Item".ljust(8, "-") == "Item----"
assert "Data".ljust(10, ".") == "Data......"
# 3. Column formatter with safety truncation
assert formatter.format_column("Short", 10) == "Short "
assert formatter.format_column("VeryLongEnterpriseName", 12, max_len=12) == "VeryLongE..."
# 4. Dot leader formatting
dl = formatter.format_dot_leader("Network Check", "[OK]", 30)
assert dl.startswith("Network Check ")
assert dl.endswith(" [OK]")
assert len(dl) == 30
# 5. TypeError validation on invalid fillchar
try:
"test".ljust(10, "--")
assert False, "Expected TypeError not raised"
except TypeError as e:
assert "must be exactly one character" in str(e)
print("Formatted col: ", repr(formatter.format_column("Admin", 12)))
print("Dot leader line:", dl)
print("All str.ljust() unit assertions passed successfully!")
Open in Google Colab View on GitHub
Run all left-alignment examples interactively, contrast ljust() with rjust(), build tabular text outputs, and test dot-leader formatting in Google Colab.
Author & Instructor at plus2net
I write and maintain practical tutorials on Python, PHP, SQL, JavaScript, HTML, jQuery, and web development at plus2net. The tutorials focus on clear explanations, working examples, and code that readers can test and adapt while learning.