数组和数组列表
了解 PowerShell 和 Python 中的数组,以及 PowerShell 中的 ArrayList。
数组
PowerShell 中的 数组 是一种不可变(大小固定)的数据结构,可以存储异构元素。
PowerShell 中的数组是隐式类型的,但如果我们希望创建强类型数组,也可以将变量显式转换为数组类型,例如 string[]、long[] 或 int32[]。
1## 创建数组 2$array = 1,2,3,4,5 # 同质数组 3Write-Host $array 4$array = 1, 2, 'text', 1.5 # 异构数组 5Write-Host $array 6$array.gettype() # 获取数组的数据类型 7 8[int[]] $array = 1,2,3,4,5 # 强类型整数数组 9Write-Host $array 10## 强类型数组可以将不同数据类型的元素转换为定义的类型(如果转换可行) 11## 如 [double] 转 [int] 或 [char] 转 [int] 12[int[]] $array = 1,2.1,3,4.3,5,[char]'a' 13Write-Host $array 14## 抛出错误:'Cannot convert value "text" to type "System.Int32".' 15## 因为 [string] 无法转换为 [int] 16[int[]] $array = 1, 2, 'text', 1.5
Python 没有原生的数组数据结构,但可以通过内置模块 array 来支持数组。使用前必须导入该模块。Python 数组中的元素受数据类型限制,因此是同质的。这意味着字符数组只能存储字符元素,而 PowerShell 数组可以存储异构元素。
在 Python 中定义数组时,必须在创建时通过一个 类型码 指定数据类型,类型码是一个单字符。
| 类型码 | C 类型 | Python 类型 | 最小字节数 |
|---|---|---|---|
| 'c' | char | 字符 | 1 |
| 'b' | signed char | int | 1 |
| 'B' | unsigned char | int | 1 |
| 'u' | Py_UNICODE | Unicode 字符 | 2 |
| 'h' | signed short | int | 2 |
| 'H' | unsigned short | int | 2 |
| 'i' | signed int | int | 2 |
| 'I' | unsigned int | long | 2 |
| 'l' | signed long | int | 4 |
| 'L' | unsigned long | long | 4 |
| 'f' | float | float | 4 |
| 'd' | double | float | 8 |
1## 导入模块,因为 Array 不是原生数据结构 2import array 3a = array.array("I", [1,2,3,4,5]) # 同质、强类型数组 4print(type(a)) # 获取数组的数据类型 5## 不会自动类型转换,必须显式将元素转换为数组的数据类型 6a = array.array("I", [1,2,3, int(4.3), 5]) 7 8## 数组操作 9a.insert(1, 7) # 插入元素 10print(a) 11a.pop(3) # 删除并返回元素 12print(a) 13a.reverse() # 反转数组 14print(a)
1a = array.array("I", [1,2,3,4.3,5])
这会在 Python 中引发错误。
TypeError: integer argument expected, got float
关键要点
-
PowerShell 数组
- 不可变
- 同质或异构
- 松散类型
- 内置
-
Python 数组
- 可变
- 同质
- 严格类型
- 非内置,需导入
- 通常比列表更高效且更快(尽管具体性能取决于使用场景)
ArrayList (.Net)
我们刚刚学习了 PowerShell 的默认数组,它们非常有用,因其灵活性和能够在一个数组中存储任意数据类型(包括 $null)的异构对象。
1$array = 'hello world!', 111, 13.14, (Get-Date), $null
然而,这种灵活性也带来了一些缺点:
-
由于元素是异构的,我们无法保证所有元素都是特定类型,也无法强制统一转换为单一数据类型。由于 PowerShell 可以访问 .NET 类型系统,我们可以克服这些缺点,通过类型转换或类型约束变量来创建仅限于特定类型的数组:
1[int[]] $Array = 1, 2, 3 -
PowerShell 数组是不可变的,意味着其大小固定,一旦定义后就无法添加新元素。要解决这个问题,需要将新元素与原有元素合并,并将全部元素重新赋值给数组变量。
1# 数组 2$fruits = @() 3 4# 向数组添加元素 5# 会抛出异常:“Collection was of a fixed size.” 6# 因为 PowerShell 数组变量是不可变的,即使是空数组也不允许修改 7$fruits.Add('apple') 8$fruits.IsFixedSize # 输出:True 9# 因为赋值会导致大小改变,这是不允许的 10 11# 正确的添加方式,这样可以工作! 12# 因为在后台会创建一个全新的数组 13# 包含新值,然后丢弃旧数组。 14$fruits += 'apple' 15$fruits += 'banana' 16$fruits += 'orange'
PowerShell 还可以使用 .Net 类:System.Collections.ArrayList,这类集合是可变的、动态的,且性能更高。
1## ArrayList 2$names = New-Object System.Collections.ArrayList 3[void] $names.Add('Prateek') 4[void] $names.Add('Singh') 5[void] $names.Add('Prateek') 6[void] $names.Add('Singh') 7$names.IsFixedSize # 输出:False
关键要点
- PowerShell (.NET) ArrayList
- 可变
- 同质或异构
- 松散类型
- 内置