# Defining a parameter out of pairs and values

**URL:** https://discourse.julialang.org/t/defining-a-parameter-out-of-pairs-and-values/82701
**Category:** General Usage
**Tags:** question, tuple, dictionary, arrays
**Created:** [June 13, 2022, 6:43pm UTC](https://discourse.julialang.org/t/defining-a-parameter-out-of-pairs-and-values/82701 "2022-06-13T18:43:22Z")
**Posts on this page:** 19
**Page:** 1

<div class="post-metadata">

### Author: ![noja](https://avatars.discourse-cdn.com/v4/letter/n/f6c823/32.png) [@noja](https://discourse.julialang.org/u/noja)
#### Post date: [June 13, 2022, 6:43pm UTC](https://discourse.julialang.org/t/defining-a-parameter-out-of-pairs-and-values/82701/1 "2022-06-13T18:43:22Z")

</div>

I have a set of pair like the following, and each pair comes with a value attached to it. For isntance the value of a pair `(1,2)` will be `2.5`. There are another set of persons. Each person also connected to the subset of pairs. For instance, for `p` is connected to `[(1, 2), (1, 7), (2, 3)]`.

```julia

Pairs = [(1, 2), (1, 7), (2, 3), (2, 5),(3, 4), (3, 5), (4, 1), (4, 5), (5, 2)]
Values = [2.5, 4.1, 7.4, 5.6, 2.8, 3.7, 6.9, 0.2, 3.2]

Persons = ['p','q']
p_pairs = [[(1, 2), (1, 7), (2, 3)], 
              [(1, 2), (2, 3), (2, 5) ,(5, 2)] 
           ]

```

The question is, how to bulid up a parameter `person_values` such that it return the value of the associated pairs?

For instance `person_values['p',1, 2] = 2.5` and `person_values['p',2, 3] = person_values['q',2, 3] = 7.4`. In other words `person_values[{elements of p1} , { elemnts of pairs}] = related values`

---

<div class="post-metadata">

### Author: ![rafael.guerra](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rafael.guerra/32/216610_2.png) [@rafael.guerra](https://discourse.julialang.org/u/rafael.guerra)
#### Post date: [June 13, 2022, 7:17pm UTC](https://discourse.julialang.org/t/defining-a-parameter-out-of-pairs-and-values/82701/2 "2022-06-13T19:17:13Z")

</div>

Please check if this is right for you:

```julia
function person_values(person, pair, Persons, p_pairs, Pairs, Values)
    d1, d2 = Dict(Persons .=> p_pairs), Dict(Pairs .=> Values)
    haskey(d1, person) && (pair in d1[person]) ? d2[pair] : nothing
end

Pairs = [(1, 2), (1, 7), (2, 3), (2, 5),(3, 4), (3, 5), (4, 1), (4, 5), (5, 2)]
Values = [2.5, 4.1, 7.4, 5.6, 2.8, 3.7, 6.9, 0.2, 3.2]

Persons = ['p','q']
p_pairs = [[(1, 2), (1, 7), (2, 3)], [(1, 2), (2, 3), (2, 5) ,(5, 2)] ]

person_values('p', (1,2), Persons, p_pairs, Pairs, Values) # 2.5
person_values('q', (2,3), Persons, p_pairs, Pairs, Values) # 7.4

```

---

<div class="post-metadata">

### Author: ![noja](https://avatars.discourse-cdn.com/v4/letter/n/f6c823/32.png) [@noja](https://discourse.julialang.org/u/noja)
#### Post date: [June 13, 2022, 7:42pm UTC](https://discourse.julialang.org/t/defining-a-parameter-out-of-pairs-and-values/82701/3 "2022-06-13T19:42:36Z")

</div>

@rafael.guerra this is very interesting to use two dicts. Is there any way to separate pairs? Like ` person_values['p',1, 2] = 2.5` not like this pairs `person_values['p', (1, 2)] = 2.5`

---

<div class="post-metadata">

### Author: ![Henrique\_Becker](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/henrique_becker/32/15443_2.png) [@Henrique\_Becker](https://discourse.julialang.org/u/Henrique_Becker)
#### Post date: [June 13, 2022, 7:48pm UTC](https://discourse.julialang.org/t/defining-a-parameter-out-of-pairs-and-values/82701/4 "2022-06-13T19:48:13Z")

</div>

If you are not going to keep the Dicts for future lookups I really recommend just using `findfirst` and then using the index in the other `Vector`.

---

<div class="post-metadata">

### Author: ![rafael.guerra](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rafael.guerra/32/216610_2.png) [@rafael.guerra](https://discourse.julialang.org/u/rafael.guerra)
#### Post date: [June 13, 2022, 7:56pm UTC](https://discourse.julialang.org/t/defining-a-parameter-out-of-pairs-and-values/82701/5 "2022-06-13T19:56:20Z")

</div>

> [@noja](#):
>
> is there any way to separate pairs? Like ` person_values['p',1, 2] = 2.5` not like this pairs `person_values['p', (1, 2)] = 2.5`

You could accept two separate arguments to the function, and create the tuple inside it:

```julia
function person_values2(person, x, y, Persons, p_pairs, Pairs, Values)
    d1, d2 = Dict(Persons .=> p_pairs), Dict(Pairs .=> Values)
    haskey(d1, person) && ((x,y) in d1[person]) ? d2[(x,y)] : nothing
end

person_values2('p', 1, 2, Persons, p_pairs, Pairs, Values) # 2.5
person_values2('q', 2, 3, Persons, p_pairs, Pairs, Values) # 7.4

```

_NB: I’m just a user, better listen to Henrique’s advice._

---

<div class="post-metadata">

### Author: ![rocco\_sprmnt21](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rocco_sprmnt21/32/20127_2.png) [@rocco\_sprmnt21](https://discourse.julialang.org/u/rocco_sprmnt21)
#### Post date: [June 13, 2022, 8:35pm UTC](https://discourse.julialang.org/t/defining-a-parameter-out-of-pairs-and-values/82701/6 "2022-06-13T20:35:06Z")

</div>

try using this function

```julia

function person_values(person, pair...)
    get(d2,only(intersect(get(d1,person,nothing),[pair])),nothing)
end

person_values('q',2, 3)
person_values('p',1, 2) 

# or

function person_values(person, pair...)
    pp=intersect(get(d1,person,nothing),[pair])
    isempty(pp) ? nothing : get(d2,pp[1],nothing)
end

```

---

<div class="post-metadata">

### Author: ![noja](https://avatars.discourse-cdn.com/v4/letter/n/f6c823/32.png) [@noja](https://discourse.julialang.org/u/noja)
#### Post date: [June 13, 2022, 8:39pm UTC](https://discourse.julialang.org/t/defining-a-parameter-out-of-pairs-and-values/82701/7 "2022-06-13T20:39:40Z")

</div>

> [@rocco\_sprmnt21](#):
>
> `get(d2,only(intersect(get(d1,person,nothing),[pair])),nothing)`

Thanks @rocco_sprmnt21 , so, to define a parameter we should use function? always?

I was wondering why this does not work?

[get(d2,only(intersect(get(d1,person,nothing),[pair])),nothing) for person in Persons for pair in pairs]

in other word; is there a way to extent this over aloop to assign all at once?? (No function)

---

<div class="post-metadata">

### Author: ![noja](https://avatars.discourse-cdn.com/v4/letter/n/f6c823/32.png) [@noja](https://discourse.julialang.org/u/noja)
#### Post date: [June 13, 2022, 8:42pm UTC](https://discourse.julialang.org/t/defining-a-parameter-out-of-pairs-and-values/82701/8 "2022-06-13T20:42:57Z")

</div>

Actually I’m a novice and never heard of this before. Thanks for recommending @Henrique_Becker .  
I don’t know whether I’ll need to keep the dics at future, but I know I want to unpair while keeping the order of pairs (since (2,3) \<\> (3,2) )

---

<div class="post-metadata">

### Author: ![rocco\_sprmnt21](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rocco_sprmnt21/32/20127_2.png) [@rocco\_sprmnt21](https://discourse.julialang.org/u/rocco_sprmnt21)
#### Post date: [June 13, 2022, 8:58pm UTC](https://discourse.julialang.org/t/defining-a-parameter-out-of-pairs-and-values/82701/9 "2022-06-13T20:58:03Z")

</div>

> [@noja](#):
>
> [get(d2,only(intersect(get(d1,person,nothing),[pair])),nothing) for person in Persons for pair in pairs]

I’m not sure I understand what the expected result is, but I try

```julia

[(person,pair)=>person_values(person,pair...) for (person,pair) in Iterators.product(Persons,Pairs)][:]

18-element Vector{Pair{Tuple{Char, Tuple{Int64, Int64}}}}:
 ('p', (1, 2)) => 2.5
 ('q', (1, 2)) => 2.5
 ('p', (1, 7)) => 4.1
 ('q', (1, 7)) => nothing
 ('p', (2, 3)) => 7.4
 ('q', (2, 3)) => 7.4
 ('p', (2, 5)) => nothing
 ('q', (2, 5)) => 5.6
 ('p', (3, 4)) => nothing
 ('q', (3, 4)) => nothing
 ('p', (3, 5)) => nothing
 ('q', (3, 5)) => nothing
 ('p', (4, 1)) => nothing
 ('q', (4, 1)) => nothing
 ('p', (4, 5)) => nothing
 ('q', (4, 5)) => nothing
 ('p', (5, 2)) => nothing
 ('q', (5, 2)) => 3.2

#or, if you prefere

julia> [ (person,pair...)=>person_values(person,pair...) for (person,pair) in
                               Iterators.product(Persons,Pairs)][:]
18-element Vector{Pair{Tuple{Char, Int64, Int64}}}:
 ('p', 1, 2) => 2.5
 ('q', 1, 2) => 2.5
 ('p', 1, 7) => 4.1
 ('q', 1, 7) => nothing
 ('p', 2, 3) => 7.4
 ('q', 2, 3) => 7.4
 ('p', 2, 5) => nothing
 ('q', 2, 5) => 5.6
 ('p', 3, 4) => nothing
 ('q', 3, 4) => nothing
 ('p', 3, 5) => nothing
 ('q', 3, 5) => nothing
 ('p', 4, 1) => nothing
 ('q', 4, 1) => nothing
 ('p', 4, 5) => nothing
 ('q', 4, 5) => nothing
 ('p', 5, 2) => nothing
 ('q', 5, 2) => 3.2

```

---

<div class="post-metadata">

### Author: ![noja](https://avatars.discourse-cdn.com/v4/letter/n/f6c823/32.png) [@noja](https://discourse.julialang.org/u/noja)
#### Post date: [June 13, 2022, 9:08pm UTC](https://discourse.julialang.org/t/defining-a-parameter-out-of-pairs-and-values/82701/10 "2022-06-13T21:08:18Z")

</div>

Wow, all these seem very complicated. I feel lost. need to search on them soon.What I wish is just a mapping from two sets `Persons` and `p_pairs` to a given set like `values`.  
Having too much `nothing` may make the program slow? because this `person_values` parameters will later be used somewhere over a loop.

Is there any simpler way to first filter out values and then assign. Should we use function and Dict? Is there any way to just use `for`

---

<div class="post-metadata">

### Author: ![rocco\_sprmnt21](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rocco_sprmnt21/32/20127_2.png) [@rocco\_sprmnt21](https://discourse.julialang.org/u/rocco_sprmnt21)
#### Post date: [June 13, 2022, 9:41pm UTC](https://discourse.julialang.org/t/defining-a-parameter-out-of-pairs-and-values/82701/11 "2022-06-13T21:41:12Z")

</div>

Then this should be closer to your needs

```julia
[ (person,pair...)=>person_values(person,pair...) for (person,pair) in 
    Iterators.flatten([k.=>v for (k,v) in d1])]

```

which can be rewritten like this

```julia

[(p,pp...)=>d2[pp] for(p,pp) in Iterators.flatten([k.=>v for (k,v) in d1])]

7-element Vector{Pair{Tuple{Char, Int64, Int64}, Float64}}:
 ('p', 1, 2) => 2.5
 ('p', 1, 7) => 4.1
 ('p', 2, 3) => 7.4
 ('q', 1, 2) => 2.5
 ('q', 2, 3) => 7.4
 ('q', 2, 5) => 5.6
 ('q', 5, 2) => 3.2

```

---

<div class="post-metadata">

### Author: ![rafael.guerra](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rafael.guerra/32/216610_2.png) [@rafael.guerra](https://discourse.julialang.org/u/rafael.guerra)
#### Post date: [June 13, 2022, 9:42pm UTC](https://discourse.julialang.org/t/defining-a-parameter-out-of-pairs-and-values/82701/12 "2022-06-13T21:42:18Z")

</div>

> [@noja](#):
>
> Wow, all these seem very complicated.

AFAIC, sorry but simplicity requires more time and skill 🙂

---

<div class="post-metadata">

### Author: ![Henrique\_Becker](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/henrique_becker/32/15443_2.png) [@Henrique\_Becker](https://discourse.julialang.org/u/Henrique_Becker)
#### Post date: [June 14, 2022, 12:08am UTC](https://discourse.julialang.org/t/defining-a-parameter-out-of-pairs-and-values/82701/13 "2022-06-14T00:08:27Z")

</div>

As the Germans say: “Sorry for the long letter, I did not have the time to write a short one.”

---

<div class="post-metadata">

### Author: ![rocco\_sprmnt21](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rocco_sprmnt21/32/20127_2.png) [@rocco\_sprmnt21](https://discourse.julialang.org/u/rocco_sprmnt21)
#### Post date: [June 14, 2022, 4:52am UTC](https://discourse.julialang.org/t/defining-a-parameter-out-of-pairs-and-values/82701/14 "2022-06-14T04:52:29Z")

</div>

Having enough time to be shorter…

```julia
julia> [(p,pp...)=>d2[pp] for(p,pp) in vcat([k.=>v for (k,v) in d1]...)]
7-element Vector{Pair{Tuple{Char, Int64, Int64}, Float64}}:
 ('p', 1, 2) => 2.5
 ('p', 1, 7) => 4.1
 ('p', 2, 3) => 7.4
 ('q', 1, 2) => 2.5
 ('q', 2, 3) => 7.4
 ('q', 2, 5) => 5.6
 ('q', 5, 2) => 3.2

```

---

<div class="post-metadata">

### Author: ![rafael.guerra](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rafael.guerra/32/216610_2.png) [@rafael.guerra](https://discourse.julialang.org/u/rafael.guerra)
#### Post date: [June 14, 2022, 6:14am UTC](https://discourse.julialang.org/t/defining-a-parameter-out-of-pairs-and-values/82701/15 "2022-06-14T06:14:31Z")

</div>

> [@Henrique\_Becker](#):
>
> As the Germans say:

There is also the famous quote from Gauss:

_You know that I write slowly. This is chiefly because I am never satisfied until I have said as much as possible in a few words, and writing briefly takes far more time than writing at length._

---

<div class="post-metadata">

### Author: ![lmiq](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lmiq/32/18314_2.png) [@lmiq](https://discourse.julialang.org/u/lmiq)
#### Post date: [June 14, 2022, 7:19am UTC](https://discourse.julialang.org/t/defining-a-parameter-out-of-pairs-and-values/82701/16 "2022-06-14T07:19:53Z")

</div>

A more lower level alternative:

```julia
julia> function person_values(p, i, j; Persons=Persons, Pairs=Pairs, Values=Values, p_pairs=p_pairs)
           ip = findfirst(isequal(p), Persons)
           isnothing(ip) && error("Person not found")
           ipair = findfirst(isequal((i,j)), p_pairs[ip])
           isnothing(ipair) && return nothing
           ivalue = findfirst(isequal((i,j)), Pairs)
           isnothing(ivalue) && error("Value not found")
           return Values[ivalue]
       end
person_values (generic function with 1 method)

julia> person_values('q', 2, 3)
7.4

julia> @btime person_values('q', 2, 3; Persons=$Persons, Pairs=$Pairs, Values=$Values, p_pairs=$p_pairs)
  9.037 ns (0 allocations: 0 bytes)
7.4

```

ps: This is what Henrique suggested, actually.

---

<div class="post-metadata">

### Author: ![rafael.guerra](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rafael.guerra/32/216610_2.png) [@rafael.guerra](https://discourse.julialang.org/u/rafael.guerra)
#### Post date: [June 14, 2022, 11:26am UTC](https://discourse.julialang.org/t/defining-a-parameter-out-of-pairs-and-values/82701/17 "2022-06-14T11:26:41Z")

</div>

@lmiq, could you confirm whether the keyword arguments default values, in your function implementation, need to be declared as global constants outside the function for it to perform best? Thanks.

---

<div class="post-metadata">

### Author: ![lmiq](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lmiq/32/18314_2.png) [@lmiq](https://discourse.julialang.org/u/lmiq)
#### Post date: [June 14, 2022, 11:35am UTC](https://discourse.julialang.org/t/defining-a-parameter-out-of-pairs-and-values/82701/18 "2022-06-14T11:35:52Z")

</div>

I think they do.

---

<div class="post-metadata">

### Author: ![rocco\_sprmnt21](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rocco_sprmnt21/32/20127_2.png) [@rocco\_sprmnt21](https://discourse.julialang.org/u/rocco_sprmnt21)
#### Post date: [June 14, 2022, 1:11pm UTC](https://discourse.julialang.org/t/defining-a-parameter-out-of-pairs-and-values/82701/19 "2022-06-14T13:11:48Z")

</div>

the version with findfirst and without dicts

```julia
[(p,pp...)=>Values[findfirst(==(pp),Pairs)] for(p,pp) in vcat([k.=>v for (k,v) in zip(Persons,p_pairs)]...)]

```
