Julia Learner
Julia Learner

Reputation: 2912

Python-style lists in Julia

The following code acted as I expected for a Python-style list in Julia:

julia> list1 = [Any, 123]
2-element Array{Any,1}:
    Any
 123

julia> list1[1] = "ABC"
"ABC"

julia> list1
2-element Array{Any,1}:
    "ABC"
 123

However, this code did not:

julia> list2 = [Any]
1-element Array{DataType,1}:
 Any

julia> list2[1] = "ABC"
ERROR: MethodError: Cannot `convert` an object of type String to an object of type DataType

I was not expecting such a difference between:

julia> list1 = [Any, 123]
# and
julia> list2 = [Any]

So I tried using any instead of Any:

julia> list3 = [any, 123]
2-element Array{Any,1}:
    any
 123

julia> list3[1] = "ABC"
"ABC"

julia> list3
2-element Array{Any,1}:
    "ABC"
 123

That all worked, but then I tried:

julia> list4 = [any]
1-element Array{typeof(any),1}:
 any

julia> list4[1] = "ABC"
ERROR: MethodError: Cannot `convert` an object of type String to an object of type typeof(any)

What is going on with Julia's type inference that explains why list = [Any] or [any] produce error messages, as shown above, but things work Okay if another type is added at "list" creation?

EDIT

Based on helpful examples in the accepted answer below, this works for creating a Python-style "list" in Julia:

julia> pylist = Array{Any}(nothing, 5)
5-element Array{Any,1}:
 nothing
 nothing
 nothing
 nothing
 nothing

julia> pylist[1] = 123
123

julia> pylist[2] = 3.14
3.14

julia> pylist[3] = "ABC"
"ABC"

julia> pylist[4] = BigInt(12345)
12345

julia> pylist[5] = BigFloat(123.456)
1.234560000000000030695446184836328029632568359375e+02

EDIT 2

This is another example, but I have not been around Julia long enough to know if this is considered "Julian" or not. Any comments from Julia experts are appreciated:

julia> PyList(n) = Array{Any}(nothing, n)
PyList (generic function with 1 method)

For others new to Julia, these two lines of code may also be helpful

julia> Vector{Any}(nothing, 3)
3-element Array{Any,1}:
 nothing
 nothing
 nothing

julia> Vector{Any}(nothing, 3) == Array{Any}(nothing, 3)
true

Thus, a Vector{Any} in the above example is just an alias for Array{Any}. Here are some examples using PyList.

julia> pylst = PyList(3)
3-element Array{Any,1}:
 nothing
 nothing
 nothing

julia> pylst[1] = "ABC"
"ABC"  
julia> pylst[2] = 123
123
julia> pylst[3] = 3.14
3.14
julia> pylst
3-element Array{Any,1}:
    "ABC"
 123
   3.14

Upvotes: 1

Views: 6071

Answers (2)

HarmonicaMuse
HarmonicaMuse

Reputation: 7893

Python lists accept any type of element and are not of fixed size, so to make a new Vector{Any}, in Julia you just do Any[] (comments are in Python):

julia> x = Any[]        # >>> x = []
0-element Array{Any,1}  # >>> x
                        # []

julia> push!(x, 1)       # >>> x.append(1)
1-element Array{Any,1}:  # >>> x
 1                       # [1]

julia> push!(x, "2")     # >>> x.append("2")
2-element Array{Any,1}:  # >>> x
 1                       # [1, '2']
  "2"

Whithout Any Julia infers the next array comprehension to be of type Vector{Int}, so you wouldn't be able to push or change it's Int elements, with elements of other types.

julia> y = Any[i^2 for i in 1:3]  # >>> y = [i**2 for i in range(1, 4)]
3-element Array{Any,1}:           # >>> y
 1                                # [1, 4, 9]
 4
 9

julia> push!(y, "16")    # >>> y.append("16")
4-element Array{Any,1}:  # >>> y
 1                       # [1, 4, 9, '16']
 4
 9
  "16"

You can create utility functions in both languages to suit your needs.

julia> list() = Any[]                  # >>> list
list (generic function with 1 method)  # <type 'list'>

julia> list(n::Integer) = Vector{Any}(undef, n)  # >>> def nlist(n):
list (generic function with 2 methods)           # ...     return [None for i in range(n)]

julia> list()           # >>> list()
0-element Array{Any,1}  # []

julia> list(3)           # >>> nlist(3)
3-element Array{Any,1}:  # [None, None, None]
 #undef
 #undef
 #undef

Upvotes: 4

user2357112
user2357112

Reputation: 280973

[Any, 123] does not mean "make a 1-element array of element type Any with single element 123". It means "make an array with elements Any and 123". The element type of Any is deduced from the elements given, as Any and 123 have completely unrelated types.

Similarly, [Any] means "make an array with single element Any". The element type is deduced as DataType.

If you want to explicitly create an array of element type Any, you can do that by putting the type in front of the literal. For example, an array of element type Any with single element nothing:

arr = Any[nothing]

There are also methods to create an array of specified size, such as

# 2x3 array of Any, all elements initialized to nothing
arr = Array{Any}(nothing, 2, 3)

Upvotes: 7

Related Questions