The notation [x, y, z] denotes a homogeneously-typed list.
So I used it as an example where type inference can figure out the type of an expression from its use, rather than from its intrinsic value.
Dynamic types only work based on the intrinsic value, so whenever a statically-typed language can figure out the correct types from context, a dynamically-typed language is going to have to require redundant type hints.
So [1, read "2", 3] is a list of ints, so the read call there is known by type inference to return an int, so the read parser chosen is the parser for ints. In Python, even if you had some value that is required to be an integer, and you wanted to parse a string to that value, you'd need to say: Int.read("1"), which is redundant.
That you don't need a type signature, or any explicit type information at all. Because the compiler already knows it has to be a list of Ints, you can just call read and it knows it has to be converting that string to an int. In a unityped language you still need to supply the information about what type to convert to.