Adding items into a tuple

1,970 views
Skip to first unread message

Alexei Serdiuk

unread,
Aug 30, 2016, 1:26:29 AM8/30/16
to julia-users
Hi,

I need to choose items from a range (1:N) according to some condition and to push them into a tuple.

I understand how to add items into an array:
t=Array()
for i = 1:N
     if condition==true
          push!(t, i)
end; end

Is there a way to push them into a tuple?

Thanks.

Chris Rackauckas

unread,
Aug 30, 2016, 1:51:51 AM8/30/16
to julia-users
Tuples are immutable by design. This is why they are fast, but also why you can't push into them.

Kristoffer Carlsson

unread,
Aug 30, 2016, 3:39:38 AM8/30/16
to julia-users
t = ()
condition
= true

for i = 1:N
   
if condition==true

        t
= (t..., i)
   
end
end


This does not modify the tuple but replaces it with a new longer one. 

Yichao Yu

unread,
Aug 30, 2016, 3:55:41 AM8/30/16
to Julia Users
On Tue, Aug 30, 2016 at 3:39 PM, Kristoffer Carlsson <kcarl...@gmail.com> wrote:
t = ()
condition
= true
for i = 1:N
   
if condition==true

        t
= (t..., i)

Note that you shouldn't do this unless you only have very few elements.

Yichao Yu

unread,
Aug 30, 2016, 3:58:00 AM8/30/16
to Julia Users
On Tue, Aug 30, 2016 at 3:55 PM, Yichao Yu <yyc...@gmail.com> wrote:


On Tue, Aug 30, 2016 at 3:39 PM, Kristoffer Carlsson <kcarl...@gmail.com> wrote:
t = ()
condition
= true
for i = 1:N
   
if condition==true

        t
= (t..., i)

Note that you shouldn't do this unless you only have very few elements.

And even then, this completely looses the advantage of using tuple (inferrable size and element types) so you shouldn't do this in general unless you are going to do a lot of work with the tiny tuple afterwards.

Alexei Serdiuk

unread,
Aug 30, 2016, 5:50:18 AM8/30/16
to julia-users
Thank you very much, it works!

I'll explain you why I want to use tuples.
I have a range of products 1:N. Every product can be made of several mutually exclusive bases. I need to make a lot of loop of this kind

for k in Products, b in Bases
     
if accordance[k,b]=true
         
...
end; end



I want to create an array of tulpes, so that I could decrease my loops to

for k in Products, b in Bases[k]

where Bases[1] is the tuple of bases for product[1]

I could use an array, but one product can correspond to different number of bases.

That's why I decided to use tuples.

Thanks again!

вторник, 30 августа 2016 г., 10:58:00 UTC+3 пользователь Yichao Yu написал:

Tim Holy

unread,
Aug 30, 2016, 6:11:50 AM8/30/16
to julia...@googlegroups.com
On Tuesday, August 30, 2016 3:57:36 PM CDT Yichao Yu wrote:
> And even then, this completely looses the advantage of using tuple
> (inferrable size and element types) so you shouldn't do this in general
> unless you are going to do a lot of work with the tiny tuple afterwards.

Right. If you want to grow a tuple, you should use "lispy recursion" so the
compiler can reason about the size, which is part of the type of the tuple.
(`for` loops are completely off the table for this kind of programming.)
Here's an example that builds a tuple of N `true`s (i.e., functionally
equivalent to `ntuple(d->true, N)`):

buildtrues{N}(::Type{Val{N}}) = _buildtrues((), Val{N}) # initialization

_buildtrues{N}(out::NTuple{N}, ::Type{Val{N}}) = out # termination

@inline _buildtrues{N}(out, ::Type{Val{N}}) =
_buildtrues((out..., true), Val{N}) # the "inner loop"

Key features include the `@inline` and the fact that `N` is available to the
type system. For a particular inferrable`N<15`, the compiler will just figure
out the end result and return that; the "apparent" recursion runs at compile
time, not runtime.

Note that if your condition isn't evaluatable at compile time, and especially
if it changes from one "iteration" to the next, then you're frankly much
better off using Arrays rather than tuples. Don't attempt to fake compile-time
evaluation using `Val` unless the condition is already embedded in the type
system (e.g., coming from an `::Array{T,N}`) or it's the same `Val` being used
bazillions of times. See http://docs.julialang.org/en/latest/manual/
performance-tips/#types-with-values-as-parameters and the section after that.

This is not just a theoretical concern: while tuples have enormous advantages
in certain settings, trying to fake this with tuples/Val and getting it wrong
could easily result in a 30-100 fold performance *penalty* compared to using
Arrays.

Best,
--Tim

Greg Plowman

unread,
Aug 30, 2016, 9:26:02 PM8/30/16
to julia-users

I could use an array, but one product can correspond to different number of bases.

That's why I decided to use tuples.

You could use an Array of (different length) Arrays, similar to Array of Tuples.


Another strategy might be to construct a vector of (Product, Base) pairs, and then iterate over this vector:

product_bases = Tuple{ProductType, BaseType}[]


for k in Products, b in Bases
   
if accordance[k,b]

        push
!(product_bases, (k,b))
   
end
end

for (k,b) in product_bases
   
...
end


Alexei Serdiuk

unread,
Aug 31, 2016, 1:57:51 AM8/31/16
to julia-users
Gred, thank you.
This is exactly want I looked for.

среда, 31 августа 2016 г., 4:26:02 UTC+3 пользователь Greg Plowman написал:
Reply all
Reply to author
Forward
0 new messages