姓名:韩宜真
学号:17020120095
转载自:https://mp.weixin.qq.com/s/g5akoLpIkn3XPrA-5y24IQ
【嵌牛导读】本文介绍了Julia 中的数据结构。
【嵌牛鼻子】数据类型
【嵌牛提问】Julia 中的数据结构是怎样的?
【嵌牛正文】
引言
在之前的 Julia 综合教程迭代中,我们介绍了如何在类型和函数中使用 Julia 的多分派(multiple dispatch)。多分派是一种简单的系统,用于在相同的方法参数下,将不同的类型应用于不同的函数调用。该结构中的关键组件是类型,更具体地说,是数据类型。
译注:多分派(multiple dispatch),又称多重派发,是某些编程语言的一种特性,函数或者方法的分配取决于运行时参数的对象类型。它是对方法调用只能由调用者决定的单分派的扩展。
数据类型是计算机编程的基础。任何编程工作都涉及操作、移动和处理基本数据类型。在该语言中创建的类型本身就是其他类型的容器,这些类型通常数据类型。
基本数据类型
我们可以在 Julia 编程语言中存储的第一种数据类型是基本数据类型。基本数据类型包括数字、文本、字符和布尔值等数据。
布尔类型
布尔类型(boolean)是指示条件是否为真的类型。布尔值既可以用 true/false(真 / 假) 表示(最终会浓缩为 1 或 0),也可以仅用表示类型条件的整数(1 或 0)表示。
typeof(true)
Bool
同样,我们也可以在 Julia 语言中将布尔值断言为表示 ture 或 false 的整数:
Bool(1)
true
整数类型
编程中的整数(integer)数据类型与数学中的整数数据类型相似。整数是没有小数值的整数。通常,当我们使用 Julia 中的整数时,我们将使用 Int64 数据类型。这意味着整数有 64 位。另外,还有 Int32 和 BigInt。
typeof(5)
Int64
浮点数类型
浮点数(float)是指在小数点以外有第二个数字的整数,或者说是一个小数值。浮点数可以被认为是两个独立的数据,整数在小数值之前,小数值在整数之后。
typeof(5.5)
Float64
复数类型和大数类型
在 Julia 语言中,复数(complex)类型浮点数经常出现。复数类型浮点数就是一个浮点数,它的值既有虚数又有实数。值得注意的是,这意味着这些类型不是真实的。通常,科学计算需要的是一个真实的数据类型,因此,你可能需要声明一些复数类型浮点数。
typeof(5.5 + 5.5im)
Complex(Float64)
该数据类型的第二部分中的“im”表示前面的数字是虚数。
另一方面,大数(big)类型是实数,但超出了大多数 64 位应用程序的能力,而且是精确的。这是 Julia 语言的一个重要的独特性,因为它允许通过多个函数传递巨大的整数和浮点数据类型而不出现问题,这是很少有编程语言能够做到的。
# Big Int
big(51515235151351335)
# Big Float
big(5.4172473471347374147)
符号类型
符号(symbol)数据类型是 Julia 语言从函数范式中提取的另一个伟大的东西。符号可以用来表示从参数到字典键的所有内容,而且它们在工作表中相当出色。通常,符号数据类型在编程语言中是一件很棒的事情,因为它基本上可以用作任何东西的标识,因此得名符号(symbol)。在 julia 中,只需在关键字前放置冒号即可写入符号,例如:
typeof(:Symbol)
Symbol
字符串类型和字符类型
字符串(string)是一个非常简单的概念,字符串是一组连续的 Unicode/ASCII 字符,它们构成了一组字符。正如在本系列第三部分中所讲的:“字符串可以通过循环来显示下一个数据类型,即字符(char)。”如果你还没阅读过第三部分,可以在这里查看:《熟悉 Julia 的循环》(Getting Familiar With Loops In Julia)
字符串用双引号分割。另一方面,字符用单引号分割。
typeof("Hello")
String
typeof('h')
char
浮点数是用来表示 ASCII 中的字符。因此,我们总是可以将字符转成浮点数:
float('5')
有趣的事实:这就是 Labelencing 的工作原理。
数据结构
所有的分类、向量和矩阵数据都只是作为其他类型的容器。以一个由多种数据类型(如整数、浮点数、布尔值或字符串)组成的数组为例。
数组类型
element_wise = [5, 10, 15, 15]
这个新的数组(array)是一个包含 4 个 int64 的数组。我们可以根据它们在数组中的位置用数字索引它们:
element_wise[1] == 5
true
element_wise[2] == 10
true
我们也可以在类型中看到这一点:
typeof(element_wise)
Array{Int64, 1}
为什么括号很重要
你可能已经注意到,每当创建数组时,它通常都在方括号的范围内。如果没有这些括号,数据集合的类型将是元组(tuple)。虽然我没有深入讨论元组,但它们是一种非常有效的数据类型,但如果你需要的是数组,元组当然并不是你想要的数据类型。
h = 5,10,15,20
typeof(h)
NTuple{4, Int64}
此外,不使用方括号的话,可能会使函数无法理解哪些参数对应哪些变量。以append!()方法为例。append!()方法有两个参数,第一个参数是你想要附加到的任何数据,第二个参数是你想要附加到它的数据。如果我们使用方括号,这是可行的,因为数据被视为一个参数。但是,如果使用逗号的话,将显示 ArgumentError。
parameters
v v
append!([5,10], 15)
parameters
v v v
append!(5,10,15)
字典类型
在 Julia 中,字典(dictionary)类型需要明确定义,否则它将返回一个元组。这是一个非常有价值的动态类型,在处理数据集或 JSON 数据时可以进一步说明这一点。
data = Dict(:A => [5,10,15], :B => [11, 12, 13)
使用字典,我们可以通过调用相应的符号键来调用数据,见下面示例:
data[:A]
[5, 10, 15]
对类型
对(pair)类型实际上是元组类型,但重要的是要认识到,对是元组,但元组并不是对。对和我们刚才用来访问字典部分内容是一样的,也可以用同样的方式来创建:
key = :A => [5,10,15]
集合类型
集合(set)类型只是从类型中提取的唯一值。例如,如果要将集合类型声明为数组,则将获得该数组中的每个唯一值:
arr = [5, 5, 7, 7, 6, 4, 5]
set = Set(arr)
println(set)
[5, 7, 6, 4]
元组类型
元组(tuple)类型是数据类型的通用结构,数据类型不一定具有定义结构。可以认为元组是一个组织较少的数组。
h = 5, 10, 15
创建类型
有时,使用 RAW 数据类型可能会非常乏味且费力,特别是当函数需要使用许多参数时更是如此。这就是结构(struct)的用武之地。创建一个结构将会生成一个可以容纳任何和预定义数据结构的新类型。我们可以通过使用struct关键字,后面跟一个定义和数据来创建一个结构。
struct typer
h
v
end
有了这个类型,我们现在就可以为它分配一个新的变量,为构造函数提供必要的数据作为参数:
w = typer(5, 10)
在这个示例中,sturct typer是保存数据h和v的新类型。我们可以通过调用struct.data来访问这个数据:
typer.h
5
typer.v
10
我们还可以通过函数传递这个类型,例如,从我们的 typer 结构中添加 h 和 v 数据:
function addtyper(typer)
return(typer.h + typer.v)
end
需要注意的是,Julia 语言中构造类型中的数据是不可变的。这可以通过在类型前放置关键字mutable来改变:
mutable struct typer
h
v
end
总结
数据类型一直是编程中非常重要的东西,这一问题在数据科学领域中得到了进一步的体现。大多数编程语言只是简单地使用数据结构和构造类型来处理数据类型。尽管如此,了解数据类型对于程序员来说非常重要。Julia 中有很多类型,有些可以自己构造,但是学习如何利用并操作这些类型,将是成为一名优秀程序员的关键。