# How to access partitions used in previous iterations of a loop over a partitioned set?

**URL:** <https://discourse.julialang.org/t/how-to-access-partitions-used-in-previous-iterations-of-a-loop-over-a-partitioned-set/96127>\
**Category:** New to Julia\
**Tags:** question, loops, iterators\
**Created:** [March 15, 2023, 12:04pm UTC](https://discourse.julialang.org/t/how-to-access-partitions-used-in-previous-iterations-of-a-loop-over-a-partitioned-set/96127 "2023-03-15T12:04:48Z")\
**Posts on this page:** 11\
**Page:** 1

<div class="post-metadata">

**Author:** ![phantom](https://avatars.discourse-cdn.com/v4/letter/p/e0b2c6/32.png) [@phantom](https://discourse.julialang.org/u/phantom)\
**Post date:** [March 15, 2023, 12:04pm UTC](https://discourse.julialang.org/t/how-to-access-partitions-used-in-previous-iterations-of-a-loop-over-a-partitioned-set/96127/1 "2023-03-15T12:04:48Z")

</div>

Suppose I am looping over a partitioned set. I would like to check a condition or compare a value in the current partition to that of a partition used in a previous iteration or to be used in a future iteration. What would be the best way to do so?

In an unpartitioned set I could perform comparisons like

```julia
set = rand(collect(1:10),100)

for k in eachindex(set)
    if k >1 
      println(max(set[k], set[k-1]))
    end
end  

```

But how would something similar be accomplished in a partitioned set of n elements? Say the goal is to compare the ith element of a partition to the corresponding element in the previous iteration. Where i = n it would be something like.

```julia
n = 5
g = Iterators.partition(set,n)

for (k,x) in enumerate(g)
    if k >1 
       println( max( x[end] , set[(k-1)*n]))
    end
end

```

Could I access the partition `x` from the `k-1` iteration or more generally the k +/- j iteration directly without having to reference `set`?

Because this would make it easier for situations where i != n or for cycling through `set` continuously where reverting to a simple `%` would yield an error when set[100] is indexed as set[0] e.g.

```julia
for (k,x) in enumerate(Iterators.cycle(g))
   if k>1 
     println( max( x[end] , set[((k-1)*n)%100]))
    end
end             

```

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:** [March 15, 2023, 12:09pm UTC](https://discourse.julialang.org/t/how-to-access-partitions-used-in-previous-iterations-of-a-loop-over-a-partitioned-set/96127/2 "2023-03-15T12:09:38Z")

</div>

something like?

```julia
prev_set = nothing
for set in sets
    if prev_set === nothing
        prev_set = set
        continue
    end
    max(set, prev_set)
end

```

---

<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:** [March 15, 2023, 12:31pm UTC](https://discourse.julialang.org/t/how-to-access-partitions-used-in-previous-iterations-of-a-loop-over-a-partitioned-set/96127/3 "2023-03-15T12:31:24Z")

</div>

It’s not entirely clear to me what various comparisons you need to do, but perhaps such a scheme (a “second-level” partition, so to speak) can be useful

```julia
g2=IterTools.partition(g,2,1)

```

---

<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:** [March 15, 2023, 3:41pm UTC](https://discourse.julialang.org/t/how-to-access-partitions-used-in-previous-iterations-of-a-loop-over-a-partitioned-set/96127/4 "2023-03-15T15:41:51Z")

</div>

> [@phantom](#):
>
> Could I access the partition `x` from the `k-1` iteration or more generally the k +/- j iteration directly without having to reference `set`?

I would say that you could handle this need via IterTools.partition(itr, n\*j,n)

---

<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:** [March 15, 2023, 4:08pm UTC](https://discourse.julialang.org/t/how-to-access-partitions-used-in-previous-iterations-of-a-loop-over-a-partitioned-set/96127/5 "2023-03-15T16:08:50Z")

</div>

or this way for general j-shift

```julia
j=3
g = Iterators.partition(set,n)
for (l,r) in zip(g,Iterators.drop(g,j))
    println( max( l[end] , r[end]))
end

```

---

<div class="post-metadata">

**Author:** ![phantom](https://avatars.discourse-cdn.com/v4/letter/p/e0b2c6/32.png) [@phantom](https://discourse.julialang.org/u/phantom)\
**Post date:** [March 16, 2023, 12:20am UTC](https://discourse.julialang.org/t/how-to-access-partitions-used-in-previous-iterations-of-a-loop-over-a-partitioned-set/96127/6 "2023-03-16T00:20:44Z")

</div>

Thanks so much! I didn’t know I could approach it like this. Just to clarify I would have to update prev\_set if I wanted to continuously compare to `set` to the set immediately preceding it?

so it would be like

```julia
prev_set = nothing
for set in sets
    if prev_set == nothing
        prev_set = set
        continue
    end
    max(set, prev_set)
    prev_set = set
end

```

Also just to make sure I understand these [soft scope](https://docs.julialang.org/en/v1/manual/variables-and-scoping/) rules correctly. This would only work within the body of a function or in a REPL right? Because Julia does not allow for the assignment to a global variable within a for loop from a file.

---

<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:** [March 16, 2023, 12:32am UTC](https://discourse.julialang.org/t/how-to-access-partitions-used-in-previous-iterations-of-a-loop-over-a-partitioned-set/96127/7 "2023-03-16T00:32:49Z")

</div>

> [@phantom](#):
>
> . This would only work within the body of a function or in a REPL right?

Outside a function you’d need to add a `global` there to resolve the scope ambiguity. But you shouldn’t be doing that anyways, just use a function.

Also, a minor detail, use

```julia
if isnothing(prevset) ...

```

instead of `prevset == nothing`.

It is a detail, but generally recommended because the `==` could be overloaded to mean something else. At least just to remove the linting in VSCode…

---

<div class="post-metadata">

**Author:** ![phantom](https://avatars.discourse-cdn.com/v4/letter/p/e0b2c6/32.png) [@phantom](https://discourse.julialang.org/u/phantom)\
**Post date:** [March 16, 2023, 1:27am UTC](https://discourse.julialang.org/t/how-to-access-partitions-used-in-previous-iterations-of-a-loop-over-a-partitioned-set/96127/8 "2023-03-16T01:27:00Z")

</div>

Thank you so much for pointing this out! I have not tried `IterTools` in Julia yet but I will look at it tonight, I’m not sure how to mark multiple solutions on the site. If you have a moment, I’m just wondering In terms of the `zip` solution, is it possible to use it with `enumerate` or `Iterators.rest`? Either of the following

```julia
for (h,l,r) in enumerate(zip(g,Iterators.drop(g,j)))
      if h % K = 0 
         fun( l[end], r[end])
      end
end 

for (l,r) in Iterators.rest(zip(g,Iterators.drop(g,j), start)
    println(l,r)
end 

```

results in a `BoundsError`

---

<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:** [March 16, 2023, 7:38am UTC](https://discourse.julialang.org/t/how-to-access-partitions-used-in-previous-iterations-of-a-loop-over-a-partitioned-set/96127/9 "2023-03-16T07:38:08Z")

</div>

It’s not clear to me what the purpose of these lines is, but still if you change like this you don’t get the BoundsError:

```julia
j=2
K=3
for (h,(l,r)) in enumerate(zip(g,Iterators.drop(g,j)))
    if h % K == 0 
       max( l[end], r[end])
    end
end 

```

in these cases, to debug, I try to see what’s inside some parts.  
For example if I do `collect(zip(g,Iterators.drop(g,j)))` I see what the iterator contains and what shape. So I understand that they are tuples of two elements of which the second is, in turn, a tuple.

for the second part what do you want to achieve?

PS

I doubt that it is not clear what the snippet that I have proposed does.  
I try to describe it below.

1. The function g=partition(itr,n) creates the iteratoreg containing the successive blocks of n-elements.
2. drop(g, j) drops the first j blocks (rest(g,j) would take blocks from j onwards)
3. zip(g, drop(g,j)) creates the iterator of the pairs of blocks. Thus the first pair is (g[1], g[j+1]) (that is, in fact, the first and j+1-th group of g) ; the second (g[2], g[j+2]) (that is, in fact, the second and the j+2-th group of g), etc. until the shortest iterator is consumed.

---

<div class="post-metadata">

**Author:** ![phantom](https://avatars.discourse-cdn.com/v4/letter/p/e0b2c6/32.png) [@phantom](https://discourse.julialang.org/u/phantom)\
**Post date:** [March 16, 2023, 11:17am UTC](https://discourse.julialang.org/t/how-to-access-partitions-used-in-previous-iterations-of-a-loop-over-a-partitioned-set/96127/10 "2023-03-16T11:17:35Z")

</div>

Thanks so much for this detailed explanation. Sorry a quick confirmation on why the added `()` in `(h,(l,r))` removes the bounds error because I want to make sure I understand the dynamic correctly.

Given

```julia
j = 2
g = Iterators.partition([1:10;],2)

```

then

```julia
julia> collect(enumerate(zip(g,Iterators.drop(g,j))))
3-element Vector{Tuple{Int64, Tuple{SubArray{Int64, 1, Vector{Int64}, Tuple{UnitRange{Int64}}, true}, SubArray{Int64, 1, Vector{Int64}, Tuple{UnitRange{Int64}}, true}}}}:
 (1, ([1, 2], [5, 6]))
 (2, ([3, 4], [7, 8]))
 (3, ([5, 6], [9, 10]))

```

Means the ` x` in `for x = set` has to follow the same format of `( _ ,( _ ,_ ) )` or `( _ , ( _ _ ), ( _ _ ))` ?

In terms of the `Iterators.rest()` I was thinking of a hypothetical that required cycling through the set `zip(g,Iterators.drop(g,j))` where `cycle()` is initiated at position n determined by an input in the function.

In the above example, it would be something like

```julia
(1,([2,3], [6,7])) # enumerated first iteration starting at the second position of the `zip` set 
(2,([4,5], [8,9])) # the loop terminates upon the last complete tuple  

```

After playing around with `collect` as you mentioned, I was able to get something similar with.

```julia
collect(enumerate(zip(Iterators.rest(g,2),Iterators.drop(Iterators.rest(g,2),j))))
3-element Vector{Tuple{Int64, Tuple{SubArray{Int64, 1, Vector{Int64}, Tuple{UnitRange{Int64}}, true}, SubArray{Int64, 1, Vector{Int64}, Tuple{UnitRange{Int64}}, true}}}}:
 (1, ([2, 3], [6, 7]))
 (2, ([4, 5], [8, 9]))
 (3, ([6, 7], [10]))

```

---

<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:** [March 16, 2023, 11:41am UTC](https://discourse.julialang.org/t/how-to-access-partitions-used-in-previous-iterations-of-a-loop-over-a-partitioned-set/96127/11 "2023-03-16T11:41:24Z")

</div>

> [@phantom](#):
>
> Means the ` x` in `for x = set` has to follow the same format of `( _ ,( _ ,_ ) )` or `( _ , ( _ _ ), ( _ _ ))` ?

depends on what you want to do with it, you can use one or the other of the shapes

```julia
julia> cez=collect(enumerate(zip(g,Iterators.drop(g,j))))       
3-element Vector{Tuple{Int64, Tuple{SubArray{Int64, 1, Vector{Int64}, Tuple{UnitRange{Int64}}, true}, SubArray{Int64, 1, Vector{Int64}, Tuple{UnitRange{Int64}}, true}}}}:
 (1, ([1, 2], [5, 6]))
 (2, ([3, 4], [7, 8]))
 (3, ([5, 6], [9, 10]))

julia> (a,(b,c))=cez[1]
(1, ([1, 2], [5, 6]))

julia> a
1

julia> b
2-element view(::Vector{Int64}, 1:2) with eltype Int64:
 1
 2

julia> c
2-element view(::Vector{Int64}, 5:6) with eltype Int64:
 5
 6

# or 

julia> (a,((b1,b2),(c1,c2)))=cez[1]
(1, ([1, 2], [5, 6]))

julia> a
1

julia> b1
1

julia> b2
2

julia> c1
5

julia> c2
6

```
