Index Of Ovum
IndexOf Ovum — the Python-list flavor of 'where is this value in my list?'
- py_list
- search_element
- INT
This is the "search a Python list for a value" node in its current, non-deprecated form. Same promise as the rest of the family: give it a list and a target, get back the index of the first match, or -1 if the value isn't there. What makes this variant worth picking is that it's tuned for the case where py_list arrives as a single Python list object - the kind of thing a From List Type, a string-list editor, or another utility node hands you - rather than a Comfy batch structure.
The mechanism is simple and worth understanding because it determines the output contract: it scans the list left to right using Python ==, returns the first index whose element compares equal, and never mutates the input. That equality check is strict, so 2 the integer and "2" the string are different animals - a classic source of "why is it returning -1?" confusion when you're pulling values from text widgets.
Inputs and output
Only three inputs, straight from the schema:
py_list- the Python list to search. Must genuinely be a list; anything else throwsValueError.search_element- the value to find. Any type.start- optional from-index, entered as aSTRING. Blank/whitespace → 0; negative → counts from the end, clamped to[0, n].
Output: one INT, the first matching index or -1. Wire it into IfElseOvum, CompareOvum, or a Get-by-index node and you've got cheap list-based routing: "does this filename exist in the batch, and if so, where?"
The "python" vs "comfy" split, briefly
sfinktah maintains parallel list nodes across categories - ovum/lists/comfy (the Batch variants) and ovum/lists/python (these Ovum ones). They're near-identical code, and the honest answer is that the pack doesn't draw a crisp line between them in the README. The practical rule: if the value on your wire is a Python list object produced by a list utility, reach for IndexOfOvum; if it's a Comfy-style batch/list you built from a fan-out, IndexOfBatchOvum tends to fit. Either way the inputs and the -1 contract are the same, so you can swap without re-wiring much.
A shared gotcha: these nodes inherit NewPointer, which makes ComfyUI treat them as always-changed (IS_CHANGED returns NaN), so they never get cached out of a run. That's good for loop counters and fresh list checks, and mildly wasteful if you hoped ComfyUI would skip redundant work.
Install and gotchas
It comes with comfy-ovum, installed once:
cd ComfyUI/custom_nodes
git clone https://github.com/sfinktah/comfy-ovum
or via ComfyUI Manager → comfy-ovum, then restart. No models, no keys.
If you see ValueError: Input must be a Python list, whatever you wired in isn't a list - the node is strict on purpose. If you get -1 against a value you can see in the list, check start (it's a string; leftover whitespace shifts the scan) and double-check types on both sides of the comparison.
Inputs (3)
| Name | Type | Default | Description |
|---|---|---|---|
| py_list | * | — | |
| search_element | * | — | |
| start | STRING | — |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| INT | INT | — |