Is there a Julia equivalent for python's .remove() function?

I have tried deleteat!(arr, findfirst(item,arr)) but it gives me an error. Is it deprecated?

You can try popfirst! if you just want to remove the first element of the array.

You probably want:

findfirst(isequal(item), arr)

to get the index of the first item which is equal to item.

This behavior changed in Julia 1.0, so if you have other old code you might find that running it in Julia 0.7 is helpful, since it will tell you exactly what changed and how to fix your code:

julia-0.7> findfirst(1, [1, 2, 3])
┌ Warning: `findfirst(A, v)` is deprecated, use `something(findfirst(isequal(v), A), 0)` instead.
│   caller = top-level scope at none:0
└ @ Core none:0
0
3 Likes

findfirst(isequal(item), arr) gives me the error LoadError: MethodError: no method matching iterate(::Nothing)

Here is the block of code where it is for some context:

coord = [(i, j) for i = 1:3 for j = 1:3]
corners = [(i, j) for i = 1:2:3 for j = 1:2:3]
for i = 1:3
    for j = 1:3
        (i, j) in coord ? deleteat!(corners, findfirst(isequal((i, j)), corners)) :
        push!(coord, (i, j))
    end
end

It’s not the completed code, but this is the general part that the issue is in…

Also how would you run julia 0.7 in the REPL?

Presumably this error happens when you call deleteat! with that result? It’s much easier to help if you can provide a way to actually reproduce the error and/or a complete backtrace.

I assume that what’s happening is that arr does not contain item. In that case, findfirst returns nothing:

julia> arr = [1, 2, 3]
3-element Array{Int64,1}:
 1
 2
 3

julia> findfirst(isequal(4), arr)

julia> findfirst(isequal(4), arr) === nothing
true

And deleteat! does not accept nothing (unsurprisingly):

julia> deleteat!(arr, findfirst(isequal(4), arr))
ERROR: MethodError: no method matching iterate(::Nothing)  

Note that you get an error in python as well:

In [1]: [1, 2, 3].remove(5)
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-1-c5f0d54cbcf3> in <module>()
----> 1 [1, 2, 3].remove(5)

ValueError: list.remove(x): x not in list

although admittedly it’s more obvious.

There may not be a built-in function that does exactly what you want in this case. You might need to write one:

function remove!(collection::AbstractVector, item)
  index = findfirst(isequal(item), collection)
  if index === nothing
    error("$item is not in $collection")
  else
    deleteat!(collection, index)
  end
end
julia> arr = [1, 2, 3]
3-element Array{Int64,1}:
 1
 2
 3

julia> remove!(arr, 1)
2-element Array{Int64,1}:
 2
 3

julia> arr
2-element Array{Int64,1}:
 2
 3

julia> remove!(arr, 4)
ERROR: 4 is not in [2, 3]
2 Likes

To run a new Julia version, you need to download it from https://julialang.org/downloads/oldreleases.html and then just ensure it’s available on your path. I wrote up my personal workflow for dealing with multiple Julia versions here: Transitioning from Ubuntu PPA to official binaries - #2 by rdeits and I’ve been pretty happy with it.

2 Likes

Isn’t this the function delete! ?

This gives the error MethodError: no method matching findfirst(::Bool, ::Array{Tuple{Int64,Int64},2})

Does delete! work with arrays? It gives me an error and the docs only mentions dictionaries/idsets

Ah no, apparently not, as methods(delete!) shows. (I wasn’t at my computer.)

You need to post a minimal working example to get better help: exactly what input and what output do you need?

1 Like

@dpsanders
Here is one instance of when I want to use it. I am doing a tic tac toe program and I want to iterate through the corners

# Corner check
  corners = [(i, j) for i = 1:2:3 for j = 1:2:3]
  while length(corners) > 1
    corner_choice = corners[rand(1:length(corners))]
    if corner_choice in coord
      board[corner_choice[1], corner_choice[2]] = current_player
      return
    else
      deleteat!(corners, findfirst(isequal(corner_choice), corners))
    end
  end

When you make the choice of a random element in the list, you are choosing the index. Just store that and use it.

2 Likes

@dpsanders
That approach wouldn’t work for this part though… (checking for spaces and updating a separate array with coordinates)

for i = 1:3
    for j = 1:3
      if board[i, j] == " "
        if (i, j) in coord
          deleteat!(coord, findfirst(isequal(i, j), coord))
        else
          push!(coord, (i, j))
        end
      end
    end
  end

I ended up using a work around by iterating with a pairs() function and generating the tuple coordinate with math.