# Subset a NamedTuple?

**URL:** <https://discourse.julialang.org/t/subset-a-namedtuple/127085>\
**Category:** General Usage\
**Created:** [March 18, 2025, 8:01am UTC](https://discourse.julialang.org/t/subset-a-namedtuple/127085 "2025-03-18T08:01:44Z")\
**Posts on this page:** 7\
**Page:** 2

<div class="post-metadata">

**Author:** ![ryofurue](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ryofurue/32/24531_2.png) [@ryofurue](https://discourse.julialang.org/u/ryofurue)\
**Post date:** [March 19, 2025, 4:53pm UTC](https://discourse.julialang.org/t/subset-a-namedtuple/127085/21 "2025-03-19T16:53:17Z")

</div>

> [@Nathan\_Boyer](#):
>
> I accept that possibility for the simplicity

I forgot to mention one more thing: Your method is “simple” to you because your functions don’t have optional arguments. Is that right? My functions very often have optional arguments, where you can omit some of the arguments. To adopt your catch-all `NamedTuple` method, you would have to write a more complicated wrapper:

```julia
# -- in one module
function f(; x = "hello", y = 3.14, z = nothing)
  @show x, y, z
end
# The simple version doesn't allow for optional arguments:
# f(nt::NamedTuple) = f(; nt.x, nt.y, nt.z)
# We need the following to allow for optional arguments:
function f(nt::NamedTuple)
  args = ()
  if haskey(nt, :x)
    args = (; x = nt.x,)
  end
  if haskey(nt, :y)
    args = (; args..., y = nt.y)
  end
  if haskey(nt, :z)
    args = (; args..., z = nt.z)
  end
  f(; args...) # Typo fixed (30 min after the posting)
end

#function g(; x = "hello", y = 3.14, z = nothing)
# @show x, y, z
#end

read_data() = (x = "x", z = "z", y = "y")

# -- in the main program
vars = read_data()

nt1 = vars[(:x,:z)] # Omit :y .
nt2 = (; vars[(:x,:z)]..., y = "replaced")

f(nt1) # works
f(nt2) # works
f(; x = "x") # I sometimes call the original interface.

```

In the first call, you omit “y” because you want to let the function use its own default value. The 3rd call is to the original interface.

If I write the complicated `f(nt::NamedTuple)` version, then I’d also include the check in the `f(nt::NamedTuple)` to detect misspelt or extraneous arguments. Then, the `f(nt::NamedTuple)` would become as robust as I want.

```julia
If you want more robust control, I suggest writing function methods for custom composite types instead of NamedTuple or kwargs....

```

Sorry I don’t understand your point. I don’t think my method as I have shown earlier needs more improvements: I just maintain the strict interface without introducing the catch-all `NamedTuple` on the function side. To manage the variables to be sent to the function, I manipulate the `NamedTuple` on the caller’s side. What benefits would I get if I introduced a `NamedTuple` interface to my function `f` ?

But, I guess this is because I don’t understand what you are proposing.

---

<div class="post-metadata">

**Author:** ![Alexander\_Knudson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/alexander_knudson/32/215656_2.png) [@Alexander\_Knudson](https://discourse.julialang.org/u/Alexander_Knudson)\
**Post date:** [March 22, 2025, 4:20am UTC](https://discourse.julialang.org/t/subset-a-namedtuple/127085/22 "2025-03-22T04:20:02Z")

</div>

I had created a Chat GPT tailored to Julia with a pdf copy of the documentation at its disposal. It was able to come up with the simple solution.

 ![IMG_2110](https://global.discourse-cdn.com/julialang/original/3X/8/7/874a070e4cecbe1d2434e93a1ae4e09c83030e35.png)

---

<div class="post-metadata">

**Author:** ![ryofurue](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ryofurue/32/24531_2.png) [@ryofurue](https://discourse.julialang.org/u/ryofurue)\
**Post date:** [April 1, 2025, 5:41am UTC](https://discourse.julialang.org/t/subset-a-namedtuple/127085/23 "2025-04-01T05:41:50Z")

</div>

Looks wonderful. Do you mean that there is a public website for your ChatGPT customization?

---

<div class="post-metadata">

**Author:** ![Sevi](https://avatars.discourse-cdn.com/v4/letter/s/c67d28/32.png) [@Sevi](https://discourse.julialang.org/u/Sevi)\
**Post date:** [April 1, 2025, 7:21am UTC](https://discourse.julialang.org/t/subset-a-namedtuple/127085/24 "2025-04-01T07:21:53Z")

</div>

Sorry for piling on a solved topic, but I just wanted to highlight @Eben60 's answer, which looks similar to the originally proposed version

```julia
vars = read_data() # returns a large NamedTuple
subset = vars[(:a, :x, :q, :ii)] # Needs only a subset
func_with_optional_keyword_args(; subset...)

```

but has the advantage that the “extracted” parts of the tuple are also available in the local scope without needing to write `nt.a` multiple times, e.g.

```julia
(; a, x, q, ii) = read_data()
func_with_optional_keyword_args(; a, x, q, ii)

# Can also use `a` in the following

```

It makes it very clear what is used where, but it does require writing out the variable names twice though.

---

<div class="post-metadata">

**Author:** ![digital\_carver](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/digital_carver/32/33818_2.png) [@digital\_carver](https://discourse.julialang.org/u/digital_carver)\
**Post date:** [April 1, 2025, 7:30am UTC](https://discourse.julialang.org/t/subset-a-namedtuple/127085/25 "2025-04-01T07:30:01Z")

</div>

I believe he’s created a “Custom GPT” which is a ChatGPT Plus feature. It doesn’t seem to be publicly available, or at least I couldn’t find it (Julia being such a common name doesn’t help either), but if the Julia manual is the only customization, it should be easy enough to replicate.

---

<div class="post-metadata">

**Author:** ![Alexander\_Knudson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/alexander_knudson/32/215656_2.png) [@Alexander\_Knudson](https://discourse.julialang.org/u/Alexander_Knudson)\
**Post date:** [April 1, 2025, 4:56pm UTC](https://discourse.julialang.org/t/subset-a-namedtuple/127085/26 "2025-04-01T16:56:48Z")

</div>

As @digital_carver said, it’s a custom GPT that has instructions to reference the documentation and github repository when responding to prompts. It was private before, but I made it available through this link: [https://chatgpt.com/g/g-67b8b2d698a481918d45d117c8cf1acd-julia-gpt](https://chatgpt.com/g/g-67b8b2d698a481918d45d117c8cf1acd-julia-gpt)

---

<div class="post-metadata">

**Author:** ![ryofurue](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ryofurue/32/24531_2.png) [@ryofurue](https://discourse.julialang.org/u/ryofurue)\
**Post date:** [April 2, 2025, 2:57am UTC](https://discourse.julialang.org/t/subset-a-namedtuple/127085/27 "2025-04-02T02:57:10Z")

</div>

> [@Sevi](#):
>
> It makes it very clear what is used where, but it does require writing out the variable names twice though.

Thank you for the idea. That sometimes works. But, I actually have functions that use different subsets of the dataset that includes many variables. That means I would end up writing out many variables like this:

```julia
(; a, x, q, ii, p, z, y) = read_data()
u = f(; z, y)
v = g(; u, ii, q)
. . .

```

The problems with this approach are

1. The list sometimes becomes too long; I sometimes need two lines to receive the variables from my data-generating function like `read_data()` when some of the names are longer.
2. I would end up spilling little names like `x`, `z`, . . . into the current scope.

It’s very uncomfortable to have may variables with short names into a single scope. (For that reason, I very often use `let` in my programs to limit the scope of local variables.) To avoid that, you want to use somewhat longer names, or to encapsulate the variables into a single object . . . for the latter purpose, `NamedTuple` is ideal (if the number of the variables are fewer than a few tens).

If you don’t have many variables, your solution is better and I would use it.

[Previous page](https://discourse.julialang.org/t/subset-a-namedtuple/127085.md?page=1)
