Lists
Stable
List syntax and operations are stable in Levython 1.0.
Lists are ordered, mutable collections that can hold values of any type. Lists in Levython are dynamically-sized arrays with O(1) amortized append and O(1) random access. They use a capacity doubling strategy for efficient memory management.
Table of Contents
Creating Lists#
Create lists with square brackets:
levython
# Empty list
empty <- []
# List of numbers
numbers <- [1, 2, 3, 4, 5]
# List of strings
names <- ["Alice", "Bob", "Carol"]
# Mixed types
mixed <- [42, "hello", true, [1, 2]]
Accessing Elements#
Access elements using zero-based indexing:
levython
colors <- ["red", "green", "blue"]
first <- colors[0] # "red"
second <- colors[1] # "green"
third <- colors[2] # "blue"
say("First color: " + first)
Modifying Lists#
Add elements with append():
levython
fruits <- ["apple", "banana"]
# Add an element
append(fruits, "cherry")
say(str(fruits)) # ["apple", "banana", "cherry"]
# Modify by index
fruits[0] <- "apricot"
say(str(fruits)) # ["apricot", "banana", "cherry"]
Iterating Over Lists#
Use for loops to iterate:
levython
numbers <- [10, 20, 30, 40]
# Iterate by value
for num in numbers {
say(str(num))
}
# Sum all elements
total <- 0
for n in numbers {
total <- total + n
}
say("Sum: " + str(total)) # Sum: 100
List Functions#
| Function | Description | Time Complexity | Example |
|---|---|---|---|
len(list) |
Get list length | O(1) | len([1,2,3]) โ 3 |
append(list, item) |
Add item to end | O(1) amortized | append(nums, 5) |
str(list) |
Convert to string | O(n) | str([1,2]) โ "[1, 2]" |
sum(list) |
Sum numeric elements | O(n) | sum([1,2,3]) โ 6 |
min(list) |
Find minimum value | O(n) | min([3,1,2]) โ 1 |
max(list) |
Find maximum value | O(n) | max([3,1,2]) โ 3 |
sorted(list) |
Return new sorted list | O(n log n) | sorted([3,1,2]) โ [1,2,3] |
reversed(list) |
Return new reversed list | O(n) | reversed([1,2,3]) โ [3,2,1] |
levython
items <- [1, 2, 3]
# Get length
size <- len(items)
say("Size: " + str(size)) # Size: 3
# Build a list
result <- []
for i in range(1, 6) {
append(result, i * 2)
}
say(str(result)) # [2, 4, 6, 8, 10]
# Aggregation functions
numbers <- [5, 2, 8, 1, 9, 3]
say("Sum: " + str(sum(numbers))) # Sum: 28
say("Min: " + str(min(numbers))) # Min: 1
say("Max: " + str(max(numbers))) # Max: 9
say("Sorted: " + str(sorted(numbers))) # Sorted: [1, 2, 3, 5, 8, 9]
List Slicing#
Extract sublists using slice notation (coming soon in Levython 1.1):
levython
# Current workaround: Manual slicing
numbers <- [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
# Extract subset using loop
subset <- []
for i in range(2, 5) {
append(subset, numbers[i])
}
say(str(subset)) # [2, 3, 4]
Multidimensional Lists#
Lists can contain other lists, creating multidimensional structures:
levython
# 2D matrix (3x3)
matrix <- [
[1, 2, 3],
[4, 5, 6],
[7, 8, 9]
]
# Access elements
first_row <- matrix[0] # [1, 2, 3]
center <- matrix[1][1] # 5
say("Center element: " + str(center))
# Iterate over 2D list
say("Matrix elements:")
for row in matrix {
for cell in row {
say(" " + str(cell))
}
}
# 3D list (2x2x2)
cube <- [
[[1, 2], [3, 4]],
[[5, 6], [7, 8]]
]
element <- cube[0][1][0] # 3
say("Cube element: " + str(element))
Performance Characteristics#
Levython lists are implemented as dynamic arrays (C++ std::vector internally) with
excellent performance characteristics:
Time Complexity
| Operation | Complexity | Notes |
|---|---|---|
Access by index: list[i] |
O(1) | Direct memory access |
Append: append(list, x) |
O(1) amortized | Capacity doubling when full |
Length: len(list) |
O(1) | Stored as metadata |
| Iteration | O(n) | Cache-friendly linear scan |
Sort: sorted(list) |
O(n log n) | Optimized quicksort/mergesort |
Memory Efficiency
- NaN-Boxed Values: Each list element is exactly 8 bytes (13x smaller than naive implementations)
- Capacity Management: Lists automatically resize with 2x growth factor for O(1) amortized append
- Contiguous Memory: Elements stored sequentially for optimal CPU cache utilization
- Zero-Copy Iteration: For loops access list elements directly without allocation
Performance: Levython lists are as fast as C++ vectors. Random access is ~1-2ns per element,
and iteration throughput exceeds 1GB/s on modern CPUs due to cache-friendly layout and JIT-optimized loops.
Best Practices
levython
# Good: Pre-allocate if size is known (future feature)
# For now, append is already optimized
# Good: Use sorted() instead of manual sorting
numbers <- [5, 2, 8, 1, 9]
sorted_nums <- sorted(numbers)
# Good: Use sum() instead of manual accumulation
total <- sum(numbers) # Faster than manual loop
# Good: Direct iteration is fastest
for item in list {
# Process item
}
# Avoid: Repeated concatenation (creates copies)
# Better to use append() which mutates in-place