Repository navigation
1.7.0 - mojo 1.1.0
Highlights:
- Compiles on mojo 1.1.0
- Reduced memory footprint by ~50% (still a ways to go)
- improved iterator methods
- 2D Indexing for CsvReader
- on average ~20% faster parsing
- CsvDictReader no longer in "beta"
- CsvWriter no longer in "beta"
- Python Shim (still needs some work)
2D indexing
The grid is row-major: reader[row, col] returns the cell at that position.
reader[0, 0] # first cell
reader[2, 5] # third row, sixth columnIterating rows
for row in reader: yields row views. A row view shares the reader's parsed
cells (cheap to copy) and can be indexed by column.
for row in reader:
print(row[0], row[1]) # cells by columnRow views are also available explicitly:
var row = reader.row(2) # third row
print(len(row)) # number of columns in the row
print(repr(row)) # ['a', 'b', 'c']
print(row[0]) # first cell of row 2DictCsvReader
Reads a CSV as rows of dicts keyed by the header row. All rows share one
refcounted header list, so rows are cheap to copy.
from mojo_csv import DictCsvReader
from std.pathlib import Path
def main() raises:
var dr = DictCsvReader(
in_csv: Path,
delimiter: String = ",",
quotation_mark: String = '"',
num_threads: Int = 0,
)
for row in dr:
print(row.get("name"), row.get("score"))row.get(key : String) raises -> String # value for a header key
row.get_at(idx : Int) raises -> String # value by column position
row.keys() -> List[String] # header names (copy)
row.vals() -> List[String] # row values (copy)
row.col_count() -> IntCsvWriter
Encodes cells per CSV rules (quotes doubled, fields quoted when they contain
the delimiter, quotes, or newlines). Fields that are already quoted are left
as-is. Threaded by default (uses logical cores - 2).
CsvWriter(
frame: List[String], # flat cells: row-major, col_count per row
delimiter: String = ",",
quotation_mark: String = '"',
num_threads: Int = 0,
) raises
writer.write(
out_csv: Path,
col_count: Int,
include_trailing_newline: Bool = False,
) raisesfrom mojo_csv import CsvWriter
from std.pathlib import Path
def main() raises:
var cells: List[String] = ["name", "score", "alice", "95", "bob", "87"]
var writer = CsvWriter(cells)
writer.write(Path("out.csv"), col_count=2, include_trailing_newline=True)Python interop
Build the compiled bindings, then use mojo_csv from Python:
(Currently this is slower the python's stdlib csv parser with the ffi translation)
python/mojo_csv_bind.mojo exposes a small CPython extension module
(python/mojo_csv_bind.so) built with mojo build --emit shared-lib:
import mojo_csv_bind as mojo_csv
# one-shot helpers (each parses the file)
cells = mojo_csv.parse_csv("data.csv") # flat list[str]
rows = mojo_csv.row_count("data.csv") # int
cols = mojo_csv.col_count("data.csv") # int
cell = mojo_csv.cell("data.csv", 1, 2) # reader[row, col]
headers = mojo_csv.headers("data.csv") # list[str]
data = mojo_csv.dict_rows("data.csv") # list[dict[str, str]]
rows = mojo_csv.write_csv(cells, cols, "out.csv") # returns row count
# Reader type: parse once, then reuse the grid (recommended for repeated access)
reader = mojo_csv.Reader("data.csv")
reader = mojo_csv.Reader("data.csv", 8) # optional thread count
reader.row_count() # int
reader.col_count() # int
reader.length() # total cells
reader.cell(1, 2) # cell at row, col
reader.get_row(3) # list[str] for one row
reader.headers() # list[str]
reader.all_cells() # flat list[str]Full Changelog: v1.6.3...1.7.0