Julia 语言初学笔记

 

Julia 与 Python 的主要差异

 

 JuliaPython
if, for, while 代码块 

以 end 关键字结束,缩进不重要

无 pass 关键字

由缩进决定

有 pass 关键字

字符串引号单引号用于字符;双引号用于字符串不区分单双引号
字符串连接

字符串连接:*

字符串重复:^ 

字符串插值:$

字符串连接:+

字符串重复:*

字符串插值:% 或 format 函数

数组索引

从 1 开始(类似 R)

 

不支持负索引,末尾元素的索引为 end

从 0 开始

 

支持负索引,末尾元素的索引为 -1

切片

包含冒号后的终点元素

例:(Julia)a[2: 3] \Leftrightarrow a[1: 3](Python)

 

冒号后的终点元素不能为空,如需直至末尾的切片,须用 end

例:(Julia)a[2: end] \Leftrightarrow a[1: ](Python)

不含冒号后的终点元素

 

冒号后的终点元素可以为空,此时表示切片直至末尾

有步长的切片

a[起点: 步长: 终点]

 

例:(Julia)a[end: -1: 1] \Leftrightarrow a[: : -1](Python)

a[起点: 终点: 步长]
矩阵索引

子矩阵:

X[[1,2], [1,3]] 表示矩阵 X 的第 1、2 行和第 1、3 列的交点构成的子矩阵

 

元素索引:

(Julia)X[[CartesianIndex(1,1), CartesianIndex(2,3)]] \Leftrightarrow X[[0,1], [0,2]](Python)

子矩阵:

(Julia)X[[1,2], [1,3]] \Leftrightarrow X[np.ix_([0,1],[0,2])](Python)

 

元素索引:

X[[1,2], [1,3]] 表示矩阵 X 中索引为 [1, 1] 和 [1, 3] 所对应元素组成的向量

行连接括号反斜杠或括号
数组列优先(Fortran 模式)NumPy: 行优先(C 模式)
默认参数

每次函数调用时重新加载

 

例:

f(x=rand()) = x 每次调用时,返回一个新的随机值

g(x=[1,2]) = push!(x,3) 每次调用时,均返回[1,2,3]

不要使用可变对象作为默认值
关键字参数函数调用时,须输入关键字函数调用时,可不输入关键字,按位置顺序传参即可
% 运算符

取余运算

 

例:

7 % 3 = 1

(-7) % 3 = -1

取模运算

 

例:

7 % 3 = 1

(-7) % 3 = 2

溢出

Int 类型对应 Int32 或 Int64,数值过大时可能溢出

如需表示更大的数值,可使用 Int128, BigInt, Float64 等数据类型

 

例:2 ^ 64 == 0

int 可表示任意长度的整数,不会溢出
虚数单位imj
幂运算^**
空值nothingNone
矩阵乘法

矩阵乘法:*

按元素相乘:.*

矩阵乘法:@

按元素相乘:*

转置'NumPy: .T
多态

支持多态,同一个函数名可对应多种方法

不支持多态,函数有唯一表达

无类,只有结构体 struct,包含数据但无方法有类
调用包与模块的调用与文件结构无关代码结构取决于路径(包)和文件(模块)
条件表达式(三目运算符)

可用于变量赋值

 

例:(Julia)x > 0 ? 1 : -1 \Leftrightarrow x = 1 if x > 0 else x = -1(Python)

不可用于变量赋值
@ 运算符装饰器
异常

try - catch - finally 结构

常规工作流中不建议使用异常处理结构,可能会影响代码性能

try - except - finally 结构
条件判断须使用显式布尔值(类似 Java)

允许使用隐式布尔值(类似 C)

注:Python 语言规范中,建议尽可能使用隐式 False

局部作用域除 if 外的代码块,包括 try - catch - finally,均有局部作用域(此条同 Julia)
命名规则

变量名使用小写;

除非难于理解,否则单词之间不加下划线;

类型(Type)或模块(Module)使用双驼峰形式命名,不使用下划线形式;

函数(Function)或宏(Macro)使用小写,且不加下划线;

能够修改自变量的函数(mutating / in-place)以叹号结尾。

除类之外,均使用下划线形式命名;

类使用双驼峰形式命名;

全局变量所有字母全部大写。

 

参考资料:

Noteworthy differences from Python

 

 

Julia 的一些有趣用法

 

UTF-8

变量与函数,均可以使用 UTF-8 编码下的字符命名:

支持 markdown 方式输入特殊字符:

 

机械极小值(Machine Epsilon)

只有浮点数才有机械极小值,含义为,与下一个可表示的浮点数之间的距离

eps(T):T 为浮点数类型(Float32 / Float64),返回 1.0 与下一个可表示的浮点数之间的距离

eps(x):x 为浮点数,返回 x 与下一个可表示的浮点数之间的距离;该数值随 x 的增大而增大

上/下一个浮点数可由 prevfloat / nextfloat 函数获得

 

变量系数

系数乘法的运算优先级:低于一元运算符,高于二元运算符

不可以将括号形式的变量作为系数,乘于括号形式的变量前,否则会报函数调用的错误:

冲突解决:

  • 0x11 表示十六进制下的 11,不表示以 0 为系数乘以 x11 变量;
  • 1.5e10 或 1.5E10 表示浮点数,不表示以 1.5 为系数乘以 e11 或 E10 变量;
  • 1.5f22 表示 Float32 类型的浮点数,不表示以 1.5 为系数乘以 f11 变量,但由于大写的 F 没有该功能,故 1.5F22 正常表示以 1.5 为系数乘以 F11 变量

 

Inf 和 NaN

有关 Inf 和 NaN 的大小比较:

  • Inf 与自身相等,比除 NaN 之外的任何数都大;
  • -Inf 与自身相等,比除 NaN 之外的任何数都小;
  • NaN 不等于、不小于、不大于任何数,包括其自身

数组运算时需注意:

 

Unicode

有效的 Unicode 数值范围为:[0x0000, 0xD7FF] 和 [0xE000, 0x10FFFF],但并非所有数值均被分配字符。

单引号内使用 \u 可以表示四位十六进制数对应的 Unicode 字符;使用 \U 则表示八位十六进制数对应的 Unicode 字符,但由 Unicode 的数值范围可知,最大有效长度仅为六位十六进制数。

含有 Unicode 字符串,由于字符的长度可能超过 1 byte,某些索引可能不合法,此时可使用 firstindex, lastindex, nextind, prevind 方法:

也可用于字符遍历:

length(str, i, j) 函数用于获取位置 i 到 j 之间(闭区间)有效字符的数量:

 

三引号字符串

有关三引号字符串的缩进:

每一行的缩进程度取决于缩进最小的一行。如下所示,示例中的最后一行决定了缩进程度:

起始三引号的所在行和由空格组成的行,不决定缩进程度;起始三引号的所在行,不受缩进程度的影响:

 

复合函数、向量化函数

复合函数:

函数链:

向量化函数:点运算符

宏 @. 用于所有函数均为向量化调用时,可以简化点运算符过多的情况:

点运算符与函数链一同使用:

 

短路计算(short-circuit evaluation)

  • a && b:当且仅当表达式 a 为 true 时,计算表达式 b;
  • a || b:当且仅当表达式 a 为 false 时,计算表达式 b

不使用短路计算的布尔运算,可使用位布尔运算符:

 

循环

for 循环内定义的计数变量 i,只在循环内可见(作用域只在循环内):

for 循环可在任何容器内迭代,此时使用关键字 in 或运算符 ∈:

多层循环可组合在同一行,按照笛卡尔积迭代,如遇 break 语句,直接跳出所有循环;而多行 for 的循环遇 break 语句时,只跳出当前循环:

 

变量作用域

词法作用域(lexical scoping):

模块内定义的变量,不能在模块外重新赋值:

函数内定义的变量,作用域只在函数内:

如前所述,循环内定义的变量,作用域只在循环内:

如需在外部使用循环内迭代后的计数变量,可使用 outer 关键词:

可以使用宏 @isdefined() 来确定变量是否定义:

let 代码块:let 内定义的变量,只在内部有效,如与外部变量重名,两个变量对应的是不同的存储空间

 

常量

若对常量进行重新赋值,当赋值类型不同时,会报错;类型相同时,会报警告:

而当重新赋值不会导致数值改变时,则不会给出警告信息:

然而,若重新赋值的常量为可变对象时,会报警告:

虽然可以对常量进行重新赋值,但是这强烈不建议这种做法,改变常量的值可能导致各种以外的问题发生。

例如,当某方法引用了一个常量,且在常量值被改变前被编译时,就会一直保持使用旧的数值:

 

复合类型(结构体)

filednames 函数可用于获得其所有字段名

除其中可变对象外,各字段的值均不可变。

声明复合类型时在前面加上 mutable 关键字,即变为可变类型:

参数复合类型:

不同参数的复合类型之间不互为子类型,但可以在参数内加入 <: 或 >: 运算符获得几种类型的并集,此时父子类型关系成立:

 

元组

长度为1时,要加逗号:

可变元组:元组中的最后一个元素可为特殊类型 Vararg,即长度可变

命名元组:

 

方法

方法指的是,一个函数的一种可能行为的定义,体现了语言的多态性。

方法歧义:

NTuple 参数:

上例中另一种消除歧义的方式:

 

构造器

外部构造器:

内部构造器:(注:new 函数仅在 struct 内有定义)

new 函数可以无参:

内部构造器会抑制默认构造器:

 

自更新运算符

如在数组中使用自更新运算符,而所用数组来自其他数组的直接赋值,则原赋值数组的值不会改变;

而当自更新运算符配合向量化运算符(.)使用时,原赋值数组的值会一同改变。

 

 

参考资料:

Julia Documentation

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值