_.flatten
_.flatten turns lists of lists into one flat list
- py_list
- depth
- LIST
Lists of lists are the natural shape of a lot of ComfyUI data - a batch of tag lists, per-frame metadata, grouped results. Then you need one flat list to feed a combobox, a string joiner, or a loop. That's _.flatten. It collapses nested arrays into a single flat list, and it lets you control how deep to go.
It's one of the _.* nodes in sfinktah/comfy-ovum, generated as a wrapper around underscore3 (a Python port of Underscore.js), and it's one of the more reliably useful members of the family.
How the depth control works
This is where the node earns its keep. _.flatten recurses all the way down by default - [[1,2],[3,[4,5]]] becomes [1,2,3,4,5]. But you can cap it:
- no depth /
false/Infinity→ flatten completely. 1ortrue→ flatten only one level:[[1,2],[3,[4,5]]]→[1,2,3,[4,5]].2,3, ... → descend that many levels.
That's the "shallow vs. deep" switch from the JS docs, re-labeled depth. The brief's description spells out the same behavior: omit (or pass false/Infinity) for the deepest flatten, true or 1 for a single level.
The inputs that matter
- py_list - the nested array (loose
*; also accepts a_.CHAIN). - depth - a loose
*input accepting JSON where applicable. Default behavior (blank) is full flatten.
Output is typed LIST, so unlike half this family you know exactly what you're getting - a flat Python list, ready to wire anywhere.
Why you'd reach for it
The classic: you've got a list of per-item tag lists and you want the union of all tags to dump into a prompt or a wildcard processor. Or a list of lists of frame paths that needs to become one list for a loader. When downstream expects a single flat LIST and upstream insists on nesting, this is the glue.
Install
ComfyUI Manager, search "comfy-ovum", or by hand:
cd ComfyUI/custom_nodes
git clone https://github.com/sfinktah/comfy-ovum
Restart and it's under ovum/underscore. No models, no downloads.
Honest warnings
The README's family-wide disclaimer stands: work in progress, "an absolute disaster to use in production." One behavior worth knowing: the depth value goes through JSON parsing, so type 1 as a number, and quote anything that isn't a number. And yes - feed it a _.CHAIN and you get a chain back; run _.value to get the flat list.
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. | |
| depthopt | * | depth: JSON allowed for arrays/objects where applicable. |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| LIST | LIST | — |