词汇表

Anaconda
Array Comprehension
Command line
Dictionary
Function
Immutable
List Comprehension
Package
Respectively
Floating point representation
Syntax

选择左侧的一个关键字...

Programming in JuliaLists and Tuples

阅读时间: ~45 min

Let's revisit the spreadsheet example we discussed earlier: suppose you're writing a spreadsheet application and you want to introduce some functionality for highlighting every row whose third-column value is greater than 10:

20
16
2
1
19
9
12
15
1
19
7
2
1
15
4
19
6
16
4
7
3
14
3
1
1
16
5
15
6
6
14
9
7
18
15
15
9
3
9
16
13
6
13
10
20
10
14
5
8
8
4
13
16
15
9
16
9
4
14
1
17
9
4
3
8
2
6
4
6
14
15
8
14
3
14
14
19
8
17
10
18
8
9
5
9
4
4
5
5
8
11
8
1
14
2
12
11
13
19
7

We definitely don't want to think of 100 variable names for the 100 values in the table, and we don't want to write a line of code for each row. What we need is a way to store all of the rows (or columns) in an object designed to contain many objects. Julia provides several such compound data structures, and in this section we will learn about two: arrays and tuples.

Arrays

A Array in Julia is a compound data type for storing a finite ordered sequence of Julia objects. Arrays are mutable, meaning that they can be changed.

The simplest way to produce an array in a Julia program is with a array literal, which requires listing the objects separated by commas and delimited by square brackets:

Exercise
What happens to myOtherArray in the example above if a different value is assigned to x after myOtherArray is created? ???

Solution. The list doesn't change. The object associated with the variable x is retrieved when the list is created, and after that point the list is no longer connected to the name x.

Like strings, arrays can be indexed to obtain their elements. The keyword end in an array index refers to the last index.

Subarrays can be extracted by slicing. Indexing a list with the range object i:j returns the portion of the list from the ith element to the jth element.

Exercise
If i = and j = , then myList[i:j] is equal to ["flower", true].

Range objects can include a step value between the starting and ending values. For example, A[1::9] returns the elements of A at positions 1, 3, 5, 7, and 9.

Exercise
What step value can be used to reverse a list? (Hint: you can reason it out!)

Solution. Going in reverse order through a list corresponds to stepping by -1 each time. Using the range object end : -1 : 1 to index an array reverses the array.

Arrays can be concatenated with the vcat function:

Elements can be appended to an array with push!:

To perform operations entry-by-entry on two arrays, prefix the operation with a dot:

Same idea for functions. To apply the function sin to each entry in an array of 100 equally spaced values from 0 to 2π, we would do:

This is called broadcasting.

(Note: the range function is another way to produce a range object; it allows us to specify the number of entries rather than the step size.)

Exercise
Write a function

which takes as arguments an array A and a positive integer n and rotates A by n positions. In other words, every element of the list should move forward n positions, wrapping around to the beginning if it goes off the end of the list.

Solution. We figure out where the list needs to be split and concatenate the two resulting sublists in the opposite order:

Arrays may be modified by combining indexing with assignment:

Exercise
Write a line of code which sets every even-indexed entry of an array A to zero. Note that you can get a list of n zeros fill0,n

Solution. A[2::end] = fill(0,length(A)÷2)

List comprehensions

Two of the most common ways of generating one list from another are (1) applying a given function to every element of the original list, and (2) retaining only those elements of the original list which satisfy a given criterion. These two operations are called map and filter, respectively.

square(x) = x * x

collect(map(square, 0:5)) # returns [0, 1, 4, 9, 16]

collect(filter(iseven, 0:5)) # returns [0,2,4]

The extra calls to collect in the examples above are required to see the result because map and filter are lazy: they return objects which promise to perform the specified calculation when it's needed. The function collect forces Julia to turn such objects into actual arrays.

Julia provides a convenient syntax

for both mapping and filtering: the array comprehension. It's essentially a programming version of set builder notation. For example, to square the even numbers from 0 to 4, we can use the following expression:

Let's break this example down step-by-step: the first value of 0:4 is assigned to the variable x, and then the if expression is evaluated. If it's true, the expression x^2 is evaluated and stored as the first value of the list that is to be returned. Then the second value of 0:4 is assigned to x, the condition is evaluated, and so on.

Exercise
Write an array comprehension which returns a list whose kth entry is the last digit of the kth three-digit prime number. Note: the string function converts an integer into a string.

Solution. Here's an example solution:

Exercise
Write an array comprehension which takes a array of arrays and returns only those arrays whose second element has a least five elements.

Solution. Here's one solution:

Tuples

Tuples are very similar to lists, except that tuples are immutable

.

Programmers tend to use tuples instead of lists in situations where position in the tuple carries more meaning than order. For example, perhaps the tuple assigned to row above describes a row of plants in a garden, with the three numbers indicating the number of plants, the number of weeks since they were planted, and the type of plant. We could have chosen some other order for those three values, as long as we're consistent about which position corresponds to which value. By contrast, the 22 heights of the plants on that row would typically be stored in an array, since the list order corresponds to something meaningful in that case (namely, the order of the plants in the row).

Functions often return multiple values by returning a tuple containing those values. You can access individual elements of a tuple without having to index the tuple using tuple unpacking:

The convention in Julia for values you don't want to store is to assign them to the variable whose name is just an underscore. That way you don't have to think of names for those variables, and you signal to anyone reading your code that you are not using those values.

Tuple unpacking can be combined with array comprehension syntax. If we want to extract the first element from each tuple in a list of triples, for example, we can do that as follows:

The value 1 is assigned to a, the value 2 is assigned to the underscore variable, and then the value 3 is also assigned to the underscore variable (this overwrite is no problem since we aren't using that value anyway). Then a is evaluated as the first element in the new list, and the process repeats for the remaining triples in the list.

Exercise
Write a list comprehension which adds the first two elements of each tuple in A. (So for the example above, the resulting list should be [3, 9, 15].)

Solution. Same idea:

Exercise
The fractional part of a positive real number x is the part after the decimal point: it's defined to be the positive difference between x and the greatest integer which is less than or equal to x. You can find the fractional part of x in Julia with the expression mod(x,1)

Find the fractional parts of the first 100 positive integer multiples of \pi. Use the function extrema on the resulting array to find its least and greatest values. Find the ratio of the greatest value to the least.

Solution. We use tuple unpacking to extract the min and max values from the tuple returned by the extrema function.

The result is about 56.08.

A common pattern for generating new arrays combines list comprehension, tuple unpacking, and the function zip. The zip function takes two arrays and returns a single array of pairs of corresponding entries (or three arrays, in which case it returns an array of triples, etc.). For example,

zip(["a", "b", "c"], [1, 2, 3])

returns an object which is equivalent to [("a", 1), ("b", 2), ("c", 3)].

Exercise
Suppose that H is a list which stores the heights of 100 cylinders and R is a list which stores their radii (in the same order). Write an array comprehension

which returns a list containing the volumes of these cylinders.

Solution. We zip H and R and use the volume formula \pi r^2 h:

Exercise
Write a function which takes a matrix M and an index i and returns the $i$th column of M. Assume that M is represented as an array of arrays, where each array represents a row.

Solution. We use an array comprehension to select the appropriate entry from each row.

Exercise
Write a function which reverses the words in a sentence. For simplicity, you may assume that the sentence does not contain punctuation.

Hint: The functions join and split might be helpful.

Solution. We use the string method split, which splits a string on a given character. This gives us a list of the words in the sentence, which we can reverse by indexing with a negative step and rejoin with the join method.

Bruno Bruno