PyList To List
The seam between a Python array and ComfyUI's run-once-per-item processing
- PYLIST
- *
ComfyUI has two different things that both get called "a list," and confusing them is the most common reason a workflow silently does the wrong thing. PyList To List is the node that sits exactly on that seam - which makes it sound boring, until you've spent an evening watching a node run once with a whole array instead of once per item.
Here's the distinction the pack's README hammers home, and it's worth internalizing before you touch this node. A List means ComfyUI's official List processing: a node declares its output with OUTPUT_IS_LIST, and everything downstream runs once per item. That's how you batch ten prompts through one sampler, or enumerate image paths one at a time. A PyList, by contrast, is a raw Python list value passed around as a single value - one socket, one array. Nothing iterates over it just because it exists. You can slice, merge, cast, and inspect it as a unit, and none of your downstream nodes will notice.
This node is the one-way bridge from the second world to the first. Feed it a PyList and it emits the same data, but now marked as a ComfyUI List - so the next node downstream fires once for every element.
How it works
Mechanically, the node is almost embarrassingly simple. Its run() returns the input list completely unchanged. The magic is in the declaration, not the code: the output socket is typed * and flagged OUTPUT_IS_LIST = (True,). That flag is what tells ComfyUI's executor to unroll the list and run the downstream graph once per item. So don't go looking for clever conversion logic - the whole node is a marker, and that's the point. It exists to relabel the same bytes as "this is a batch."
The one input that matters
- PYLIST - the raw Python list you want to expand. It's marked
forceInput, meaning there's no widget; you can't type values into it. It has to be wired from an upstream node that produces aPYLIST:Create PyList,Create Range,Split String's PYLIST output, orList To PyListfor the reverse direction.
The output is a single * socket in list-processing mode. Whatever it connects to runs once per item.
Where it actually fits
The typical pattern is: build a PyList, do array math on it while it's still one value (slice it, cast items, merge two of them), and only then cross over with this node when you're ready for per-item execution. It's the natural pairing with List To PyList - that one collects a ComfyUI List back into one Python list, so you can bounce between the two modes without rebuilding anything. A concrete example from the README: Split String → PyList To List, and now ten prompt lines become ten sequential generations through the same sampler.
Installing it
The pack is godmt/ComfyUI-List-Utils. Easiest route is ComfyUI Manager - search "ComfyUI-List-Utils" and hit install. Manual route:
cd ComfyUI/custom_nodes
git clone https://github.com/godmt/ComfyUI-List-Utils
Then restart ComfyUI. The nodes appear under the list_utils category. Good news: there are no model downloads and no requirements.txt to fight - the only numpy usage is in the arange/linspace generators, and ComfyUI already ships numpy. This is about as clean an install as custom nodes get.
Common issues
If you connect a PyList straight into a node that expects ComfyUI list processing and nothing iterates (or, worse, the whole array gets passed as one argument and crashes), you've crossed the seam on the wrong foot - this node is the fix. If you're going the other way and need the array as one value, grab List To PyList. The two are a matched pair and you'll eventually own both. And don't be startled by the * output socket; wildcard types are normal for any/list nodes like this one, not a sign something's misconfigured.
Inputs (1)
| Name | Type | Default | Description |
|---|---|---|---|
| PYLIST | PYLIST | Python list value to expand into ComfyUI List processing. |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| * | * | Each PyList item emitted as a ComfyUI List-processing item. |