Julia | Python | |
if, for, while 代码块 | 以 end 关键字结束,缩进不重要 无 pass 关键字 |
由缩进决定 有 pass 关键字 |
字符串引号 | 单引号用于字符;双引号用于字符串 | 不区分单双引号 |
字符串连接 | 字符串连接:* 字符串重复:^ 字符串插值:$ |
字符串连接:+ 字符串重复:* 字符串插值:% 或 format 函数 |
数组索引 | 从 1 开始(类似 R)
不支持负索引,末尾元素的索引为 end |
从 0 开始
支持负索引,末尾元素的索引为 -1 |
切片 | 包含冒号后的终点元素 例:(Julia)a[2: 3] a[1: 3](Python)
冒号后的终点元素不能为空,如需直至末尾的切片,须用 end 例:(Julia)a[2: end] a[1: ](Python) |
不含冒号后的终点元素
冒号后的终点元素可以为空,此时表示切片直至末尾 |
有步长的切片 | a[起点: 步长: 终点]
例:(Julia)a[end: -1: 1] a[: : -1](Python) |
a[起点: 终点: 步长] |
矩阵索引 | 子矩阵: X[[1,2], [1,3]] 表示矩阵 X 的第 1、2 行和第 1、3 列的交点构成的子矩阵
元素索引: (Julia)X[[CartesianIndex(1,1), CartesianIndex(2,3)]] X[[0,1], [0,2]](Python) |
子矩阵: (Julia)X[[1,2], [1,3]] 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 可表示任意长度的整数,不会溢出 |
虚数单位 | im | j |
幂运算 | ^ | ** |
空值 | nothing | None |
矩阵乘法 | 矩阵乘法:* 按元素相乘:.* |
矩阵乘法:@ 按元素相乘:* |
转置 | ' | NumPy: .T |
多态 | 支持多态,同一个函数名可对应多种方法 |
不支持多态,函数有唯一表达 |
类 | 无类,只有结构体 struct,包含数据但无方法 | 有类 |
调用 | 包与模块的调用与文件结构无关 | 代码结构取决于路径(包)和文件(模块) |
条件表达式(三目运算符) | 可用于变量赋值
例:(Julia)x > 0 ? 1 : -1 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
变量与函数,均可以使用 UTF-8 编码下的字符命名:
支持 markdown 方式输入特殊字符:
只有浮点数才有机械极小值,含义为,与下一个可表示的浮点数之间的距离
eps(T):T 为浮点数类型(Float32 / Float64),返回 1.0 与下一个可表示的浮点数之间的距离
eps(x):x 为浮点数,返回 x 与下一个可表示的浮点数之间的距离;该数值随 x 的增大而增大
上/下一个浮点数可由 prevfloat / nextfloat 函数获得
系数乘法的运算优先级:低于一元运算符,高于二元运算符
不可以将括号形式的变量作为系数,乘于括号形式的变量前,否则会报函数调用的错误:
冲突解决:
有关 Inf 和 NaN 的大小比较:
数组运算时需注意:
有效的 Unicode 数值范围为:[0x0000, 0xD7FF] 和 [0xE000, 0x10FFFF],但并非所有数值均被分配字符。
单引号内使用 \u 可以表示四位十六进制数对应的 Unicode 字符;使用 \U 则表示八位十六进制数对应的 Unicode 字符,但由 Unicode 的数值范围可知,最大有效长度仅为六位十六进制数。
含有 Unicode 字符串,由于字符的长度可能超过 1 byte,某些索引可能不合法,此时可使用 firstindex, lastindex, nextind, prevind 方法:
也可用于字符遍历:
length(str, i, j) 函数用于获取位置 i 到 j 之间(闭区间)有效字符的数量:
有关三引号字符串的缩进:
每一行的缩进程度取决于缩进最小的一行。如下所示,示例中的最后一行决定了缩进程度:
起始三引号的所在行和由空格组成的行,不决定缩进程度;起始三引号的所在行,不受缩进程度的影响:
复合函数:
函数链:
向量化函数:点运算符
宏 @. 用于所有函数均为向量化调用时,可以简化点运算符过多的情况:
点运算符与函数链一同使用:
不使用短路计算的布尔运算,可使用位布尔运算符:
for 循环内定义的计数变量 i,只在循环内可见(作用域只在循环内):
for 循环可在任何容器内迭代,此时使用关键字 in 或运算符 ∈:
多层循环可组合在同一行,按照笛卡尔积迭代,如遇 break 语句,直接跳出所有循环;而多行 for 的循环遇 break 语句时,只跳出当前循环:
词法作用域(lexical scoping):
模块内定义的变量,不能在模块外重新赋值:
函数内定义的变量,作用域只在函数内:
如前所述,循环内定义的变量,作用域只在循环内:
如需在外部使用循环内迭代后的计数变量,可使用 outer 关键词:
可以使用宏 @isdefined() 来确定变量是否定义:
let 代码块:let 内定义的变量,只在内部有效,如与外部变量重名,两个变量对应的是不同的存储空间
若对常量进行重新赋值,当赋值类型不同时,会报错;类型相同时,会报警告:
而当重新赋值不会导致数值改变时,则不会给出警告信息:
然而,若重新赋值的常量为可变对象时,会报警告:
虽然可以对常量进行重新赋值,但是这强烈不建议这种做法,改变常量的值可能导致各种以外的问题发生。
例如,当某方法引用了一个常量,且在常量值被改变前被编译时,就会一直保持使用旧的数值:
filednames 函数可用于获得其所有字段名
除其中可变对象外,各字段的值均不可变。
声明复合类型时在前面加上 mutable 关键字,即变为可变类型:
参数复合类型:
不同参数的复合类型之间不互为子类型,但可以在参数内加入 <: 或 >: 运算符获得几种类型的并集,此时父子类型关系成立:
长度为1时,要加逗号:
可变元组:元组中的最后一个元素可为特殊类型 Vararg,即长度可变
命名元组:
方法指的是,一个函数的一种可能行为的定义,体现了语言的多态性。
方法歧义:
NTuple 参数:
上例中另一种消除歧义的方式:
外部构造器:
内部构造器:(注:new 函数仅在 struct 内有定义)
new 函数可以无参:
内部构造器会抑制默认构造器:
如在数组中使用自更新运算符,而所用数组来自其他数组的直接赋值,则原赋值数组的值不会改变;
而当自更新运算符配合向量化运算符(.)使用时,原赋值数组的值会一同改变。
参考资料:
Julia Documentation