How to best assign values to multiple locations in a Vector of Vectors?

I am looking for an equivalent to myvector[locations] .= myvalue for a vector of vectors. It seems that I can assign to one location at a time. Is there a way?

myvecvec = [Int64[] for i in 1:10]
myvecvec[2] = [1,2]   # ok
locations = [3,5,6]
julia> myvecvec[locations] .= [7,8,9]
ERROR: MethodError: Cannot `convert` an object of type Int64 to an object of type Vector{Int64}

The error message seems wrong in that none of the lefthand or righthand side is an Int64?
Is this the preferred way?

[myvecvec[loc] = [7,8,9] for loc in locations]

and, subsequently, how can I make sure the myvalue which can be a single value or a vector, is made a vector (i.e. not [myvalue] as it errors when it already is a vector, and collect(myvalue) returns a zero-dimensional array for one value). Update: solved by this:

[length(myvalue)==1 ? myvecvec[loc] = [myvalue] : myvecvec[loc] = myvalue for loc in locations]

No the message is right. Julia tries to broadcast the elements of the vector on the right across the provided locations. This results in trying to slot Ints into the place of a Vector{Int} which causes the error. Note that this only happens because the Vector happens to be as long as the number of locations you provided. Try it with more or less locations to see what the error will say :slight_smile:

No definitively not. Side effects in array comprehensions is a very bad style imo. Additionally this allocates a new vector of vectors temporarily.

A simple way of achieving this multiple assignment is wrapping the right hand-side in Ref. This is the canonical way of telling that you don’t want to broadcast over the contents of something. So try:

myvecvec[locations] .= Ref([7,8,9])

Note that this really assigns them same vector to the slots in myvecvec. So if you mutate one of them all of them change:

myvecvec[locations[1]][2] = 1
myvecvec[locations[2]] # gives [7,1,9]

If you want separate copies, then I’d recommend just writing the for loop. Loops in Julia are fast. In fact broadcasting is implemented in Julia itself as a for loop.

This does not work for vectors of length 1. Just use x isa Int to check whether x is a Int or use the dispatch features of Julia.

1 Like

Thanks a lot for your answer!