_.first
_.first, with or without n
- py_list
- *
_.first is the simplest node in the underscore family, which makes it a nice place to learn how they all behave. Feed it an array and you get the first element back. Feed it an n and you get a new array holding the first n elements. That's the entire contract - and it's genuinely handy when a downstream node wants "just the first tag" or "the top three seeds."
It lives in sfinktah/comfy-ovum alongside its siblings, all generated as thin wrappers around underscore3 (a Python port of Underscore.js). The node class is UnderscoreFirst, displayed as _.first, under ovum/underscore.
The one input that matters
- py_list - the array (loose
*; also accepts a_.CHAIN). - n - optional count, default
1. Here's the subtle bit that bites people: with the defaultn=1... wait, no._.firstwithoutnreturns the element (a single value). Passingnreturns a list of that many elements.n=2on[10, 20, 30]gives[10, 20]. It does not mutate the input; you get a fresh list.
Output is a loose *, because it's either a single element or a list depending on whether you passed n. The node's status line shows the result type and a repr snippet, so you can see which came back.
Why you'd reach for it
Mostly the "peel one thing off the top" pattern: your upstream produces a list (from a batch splitter, a tag parser, a list of images) and you only want the first item to feed the rest of the pipeline. It's also a clean way to force a one-element list for nodes that expect a list rather than a scalar.
Install
The whole pack installs the same way - ComfyUI Manager, search "comfy-ovum", or:
cd ComfyUI/custom_nodes
git clone https://github.com/sfinktah/comfy-ovum
Restart ComfyUI and it's under ovum/underscore. No models, no heavy deps.
Honest warnings
The README is upfront that this family is a work in progress, "an absolute disaster to use in production" - fine for experiments, don't build a shared workflow around it. Watch the element-vs-list split: if you pass n, you get a list even when n=1. If you want "first element or a fallback when the list is empty," that's the sibling _.firstOr (this node just returns None/empty on an empty list). And as always, feeding in a _.CHAIN gives you a chain back - run _.value to unwrap.
Inputs (2)
| Name | Type | Default | Description |
|---|---|---|---|
| py_listopt | * | Primary input object (expected array). You can still pass any JSON-serializable value. Also accepts _.CHAIN to continue chaining. | |
| nopt | INT | 1 | n (int) |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| * | * | — |