# Adding list of tuples

**URL:** https://discourse.julialang.org/t/adding-list-of-tuples/88111
**Category:** General Usage
**Tags:** question
**Created:** [October 2, 2022, 7:07am UTC](https://discourse.julialang.org/t/adding-list-of-tuples/88111 "2022-10-02T07:07:49Z")
**Posts on this page:** 12
**Page:** 1

<div class="post-metadata">

### Author: ![Phuntsho](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/phuntsho/32/46546_2.png) [@Phuntsho](https://discourse.julialang.org/u/Phuntsho)
#### Post date: [October 2, 2022, 7:07am UTC](https://discourse.julialang.org/t/adding-list-of-tuples/88111/1 "2022-10-02T07:07:49Z")

</div>

I have two long lists of tuples: For instance, A1 = [(2,3),(4,5)…] and A2 = [(4,6),(2,8)…]. The first element of each tuple is common to both lists. Now I want to produce a new list, A3, such that whenever the first element is matched, second elements are added. I could do it using for loop and if condition as shown below

```julia
A3 = []
for i in A1
   for j in A2
       if i[1]==j[1]
          push!(A3,(i, i[2]+j[2])
       end
   end
end

```

Is there any way I can achieve this same result using one line using something like filter function? Thank you in advance.

---

<div class="post-metadata">

### Author: ![jar1](https://avatars.discourse-cdn.com/v4/letter/j/c0e974/32.png) [@jar1](https://discourse.julialang.org/u/jar1)
#### Post date: [October 2, 2022, 8:17am UTC](https://discourse.julialang.org/t/adding-list-of-tuples/88111/2 "2022-10-02T08:17:44Z")

</div>

You can probably use `Iterators.product` to replace the double loop, then `filter` or `Iterators.filter` to replace the `if` then `map` or `Iterators.map` to replace the `push!`.

---

<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: [October 2, 2022, 9:39am UTC](https://discourse.julialang.org/t/adding-list-of-tuples/88111/3 "2022-10-02T09:39:10Z")

</div>

> [@Phuntsho](#):
>
> `A3 = []`

Use `Tuple{Int,Int}[]` here if performance is of any concern.

(That given and inside a function, the loop is fine imo, I don’t see a one liner making that clearer)

---

<div class="post-metadata">

### Author: ![Dan](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dan/32/42581_2.png) [@Dan](https://discourse.julialang.org/u/Dan)
#### Post date: [October 2, 2022, 9:46am UTC](https://discourse.julialang.org/t/adding-list-of-tuples/88111/4 "2022-10-02T09:46:43Z")

</div>

```julia
D = Dict(first(A1).=>last(A1))
[(k,v+D[k]) for (k,v) in A2 if haskey(D,k)]

```

This can also fit in one line ;). It assumes first elements in tuples are unique in `A1` and `A2`, which looks reasonable from question.

In essence, this is a database join operation (might be more efficient to consider using DB for massive `A1` and `A2`).

---

<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: [October 2, 2022, 6:36pm UTC](https://discourse.julialang.org/t/adding-list-of-tuples/88111/5 "2022-10-02T18:36:23Z")

</div>

this could be a solution  
this also works if the first element of the pair is not unique.

```julia
A1 = [(2,3),(4,5)]
A2 = [(4,6),(2,8)]
df1=DataFrame(x=first.(A1),y=last.(A1))
df2=DataFrame(x=first.(A2),y=last.(A2))

combine(groupby(vcat(df1,df2),:x), :y=>sum)

A=vcat(A1,A2)
df=DataFrame(x=first.(A),y=last.(A))
udf=unstack(df,:x,:y, valuestransform=sum)

```

but perhaps the most “natural” is the following

```julia

d1=Dict(Pair(e...) for e in A1)
d2=Dict(Pair(e...) for e in A2)

mergewith(+, d1, d2)

```

---

<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: [October 2, 2022, 11:16pm UTC](https://discourse.julialang.org/t/adding-list-of-tuples/88111/6 "2022-10-02T23:16:45Z")

</div>

> [@rocco\_sprmnt21](#):
>
> ```julia
> d1=Dict(Pair(e...) for e in A1)
> d2=Dict(Pair(e...) for e in A2)
> mergewith(+, d1, d2)
> 
> ```

Perhaps it could be written more simply as:

```julia
d = mergewith(+, Dict(A1), Dict(A2))

```

And then to get the output as per OP do:

```julia
A3 = [(a, d[a[1]]) for a in A1]

```

---

<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: [October 3, 2022, 12:13am UTC](https://discourse.julialang.org/t/adding-list-of-tuples/88111/7 "2022-10-03T00:13:42Z")

</div>

I just want to stress that:

1. Dicts are almost certainly slower than vectors of tuples.
2. There is no reason whastosever to use any package or fancy syntax for this. The original proposal of the OP is perfectly fine if using `Tuple{Int,Int}[]` to initialize the resulting array and putting all that inside a function.
3. That above will almost certainly be _faster_ than any of the alternatives proposed here.
4. IMO, the loop much is much clearer.

The fact that one can write something like the OP did and get close to the best one can get, just being explicit about the logic of what one wants to do is a _fundamental feature_ of Julia.

edit: I’m not sure if the proposals here do the same as the OP proposal (or if they are what was expected, or not). Seems that people assumed that the first element of the tuple is equivalent to a dictionary key, which I’m not sure if is the case (are they unique?). Probably more info is necessary to actually understand what is the best approach.

---

<div class="post-metadata">

### Author: ![jar1](https://avatars.discourse-cdn.com/v4/letter/j/c0e974/32.png) [@jar1](https://discourse.julialang.org/u/jar1)
#### Post date: [October 3, 2022, 12:39am UTC](https://discourse.julialang.org/t/adding-list-of-tuples/88111/8 "2022-10-03T00:39:36Z")

</div>

It’s good that Julia can make loops performant when they are needed. However, capturing the logic of the operation in a named function like `map` allows thinking and communicating at a higher level than state-machine operations, so I like to use these functions when I can.

Here’s a C++ perspective on it:

[https://belaycpp.com/2021/06/22/dont-use-raw-loops/](https://belaycpp.com/2021/06/22/dont-use-raw-loops/)

---

<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: [October 3, 2022, 12:49am UTC](https://discourse.julialang.org/t/adding-list-of-tuples/88111/9 "2022-10-03T00:49:11Z")

</div>

There are cases and cases. But I don’t generally agree with that. Very often code becomes impossible to understand after being written with clever combinations of higher level functions. Many, many times, the loop is way the most clear thing to read.

---

<div class="post-metadata">

### Author: ![Jollywatt](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jollywatt/32/202198_2.png) [@Jollywatt](https://discourse.julialang.org/u/Jollywatt)
#### Post date: [October 3, 2022, 3:40am UTC](https://discourse.julialang.org/t/adding-list-of-tuples/88111/10 "2022-10-03T03:40:34Z")

</div>

I have nothing new to add, except that this is how I’d write the OP’s loop:

```julia
A3 = Tuple{Int,Int}[]
for i in A1, j in A2
    i[1] == j[1] && push!(A3,(i, i[2]+j[2])
end

```

(Pretty much the same!)

---

<div class="post-metadata">

### Author: ![aplavin](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/aplavin/32/222056_2.png) [@aplavin](https://discourse.julialang.org/u/aplavin)
#### Post date: [October 3, 2022, 5:49am UTC](https://discourse.julialang.org/t/adding-list-of-tuples/88111/11 "2022-10-03T05:49:34Z")

</div>

The requested operation is a join of these two lists.

```julia
julia> using FlexiJoins

julia> map(p -> (p.A1, p.A1[2] + p.A2[2]), innerjoin((;A1, A2), by_key(first)))
2-element StructArray(::Vector{Tuple{Int64, Int64}}, ::Vector{Int64}) with eltype Tuple{Tuple{Int64, Int64}, Int64}:
 ((2, 3), 11)
 ((4, 5), 11)

```

---

<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: [October 3, 2022, 7:29am UTC](https://discourse.julialang.org/t/adding-list-of-tuples/88111/12 "2022-10-03T07:29:56Z")

</div>

putting it all together, it could come like this …

```julia
[Tuple(d) for d in mergewith(+, Dict(A1), Dict(A2))]

```
