Python3之数组(array)

https://docs.python.org/3.5/library/array.html#module-array

当我们需要1000万个浮点数的时候,数组(array)的效率要比列表(list)要高得多,因为数组在背后存的并不是float对象,而是数字的机器翻译,也就是字节表述。这一点和c语言中的数组一样。

再比如说,如果需要频繁对序列做先出先进的操作,collection.deque(双端队列)的速度应该会更快。

  • 1.数组

如果我们需要一个只包含数字的列表,那么array.array比list更高效。数组支持所有跟可变序列有关的操作,包括.pop,.insert和.extend。

另外,数组还提供从文件读取和存入文件的更快的方法,如.frombytes和.tofile。

Python数组跟C语言数组一样精简。创建数组需要一个类型码,这个类型码用来表示在底层的C语言应该存放怎样的数据类型。比如b类型码代表的是有符号的字符(signedchar),array(‘b’)创建出的数组就只能存放一个字节大小的整数,范围从-128到127,这样在序列很大的时候,我们能节省很多空间。

一. array 模块就是数组,可以存放放一组相同类型的数字.

Type code

C Type

Python Type

Minimum size in bytes

Notes

‘b’

signed char

int

1

‘B’

unsigned char

int

1

‘u’

Py_UNICODE

Unicode character

2

(1)

‘h’

signed short

int

2

‘H’

unsigned short

int

2

‘i’

signed int int

2

‘I’

unsigned int

int

2

‘l’

signed long

int

4

‘L’

unsigned long

int

4

‘q’

signed long long int

8

(2)

‘Q’

unsigned long long

int

8

(2)

‘f’

float

float

4

‘d’

double

float

8

二. array 提供的方法如下

    append() -- append a new item to the end of the array
    buffer_info() -- return information giving the current memory info
    byteswap() -- byteswap all the items of the array
    count() -- return number of occurrences of an object
    extend() -- extend array by appending multiple elements from an iterable
    fromfile() -- read items from a file object
    fromlist() -- append items from the list
    frombytes() -- append items from the string
    index() -- return index of first occurrence of an object
    insert() -- insert a new item into the array at a provided position
    pop() -- remove and return item (default last)
    remove() -- remove first occurrence of an object
    reverse() -- reverse the order of the items in the array
    tofile() -- write all items to a file object
    tolist() -- return the array converted to an ordinary list
    tobytes() -- return the array converted to a string

如何构造一个array 对象

from array import array
import random 

# 构造方法如下
# array.array(typecode[, initializer])

# 构造一个空的int类型数组
arr = array('i')

arr = array('i', [0, 1, 2, 3, 4, 6, 7, 8, 9, 100])

array('f',[ random.randrange(-10,10) for  _ in range(10)])
Out[28]: array('f', [4.0, 6.0, -9.0, 7.0, -2.0, -7.0, -7.0, -5.0, -9.0, -10.0])
  • 常用方法介绍

array.typecode 用于创建数组的类型代码字符。上面的初始化数组的类型

arr2 = array('d',[2.3453,4.567])                                               
arr2.typecode
'd'

array.itemsize 内部表示中一个数组项的字节长度。

array.typecodes 包含所有可用类型代码的字符串。

import array
array.typecodes                                                              
'bBuhHiIlLqQfd'
array.index(x)  
# 方法返回x 在数组中第一次出现的下标, 下标从零开始,如果没有找到该元素会报异常.
ValueError: array.index(x): x not in list

array.buffer_info()  
Return a tuple (address, length) giving the current memory address 
-------------------------------------------------------------------------
# remove(element)  element 是要删除的元素,  该方法会删除第一次出现的元素, 如果有多次出现, 不会删除,如果希望删除所有的在array 中的元素,需要删除多次.
#  如果删除 的元素的不在 array 中, 则会抛异常  ValueError: array.remove(x): x not in list

arr.remove(0)
arr
array('i', [1, 2, 3, 4, 6, 7, 8, 9, 100, 111, 222, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9])

arr
array('i', [2, 3, 4, 6, 7, 8, 9, 100, 111, 222, 0, 2, 3, 4, 5, 6, 7, 8, 9, 0, 2, 3, 4])
arr.remove(1)
Traceback (most recent call last):
  File "<input>", line 1, in <module>
ValueError: array.remove(x): x not in list

删除array 所有的 1  
from array import array
def delete_array_element():
    arr = array('i', [1, 2, 1, 4, 1, 11, 1, 2, 1, 2, 0, 1, 2, 1, 4])
    while 1:
        try:
            arr.remove(1)
        except ValueError:
            print('delete finished.')
            break
    print(arr)

if __name__ == '__main__':
    delete_array_element()
-------------------------------------------------------------------------
# count(x)
Return the number of occurrences of x in the array.
# 返回 x 在数组中出现的次数,没有该元素则返回0 

arr = array('i', [1, 2, 45, 1, 1, 1, 0, 12, 1, 4])
arr.count(1)
5
arr.count(2)
1
arr.count(100)
0
-------------------------------------------------------------------------
# pop  删除元素,默认删除下标-1 的元素,  也可以指定 删除的位置 
# pop(i)  指定 i  的位置
arr
array('i', [3, 4, 6, 7, 8, 9, 100, 111, 222, 0, 2, 3, 4, 5, 6, 7, 8, 9])
arr.pop()
9
arr.pop()
8
arr
array('i', [3, 4, 6, 7, 8, 9, 100, 111, 222, 0, 2, 3, 4, 5, 6, 7])

arr
array('i', [3, 4, 6, 7, 8, 9, 100, 111, 222, 0, 2, 3, 4, 5, 6, 7])
# 删除第一个元素,并且返回该元素
arr.pop(0)
3
arr
array('i', [4, 6, 7, 8, 9, 100, 111, 222, 0, 2, 3, 4, 5, 6, 7])
#删除第3个元素 , 7 
arr.pop(2)
7
arr
array('i', [4, 6, 8, 9, 100, 111, 222, 0, 2, 3, 4, 5, 6, 7])
-------------------------------------------------------------------------
## insert (i,v)  i 是小标, v 带插入的元素

arr = array('i', [1, 2, 1, 4, 1, 11, 1, 2, 1, 2, 0])
arr
array('i', [1, 2, 1, 4, 1, 11, 1, 2, 1, 2, 0])
arr.insert(0,100)
arr
array('i', [100, 1, 2, 1, 4, 1, 11, 1, 2, 1, 2, 0])
arr.insert(2,200)
arr
array('i', [100, 1, 200, 2, 1, 4, 1, 11, 1, 2, 1, 2, 0])
-------------------------------------------------------------------------
## append(v)
# append 默认从末尾追加元素, 在数组尾部添加元素
arr =array('f',range(4))
arr
array('f', [0.0, 1.0, 2.0, 3.0])
arr.append(66.66)
arr.append(66.67)
arr.append(66.68)
arr
array('f', [0.0, 1.0, 2.0, 3.0, 66.66000366210938, 66.66999816894531, 66.68000030517578])
-------------------------------------------------------------------------
# extend, 通过一个可迭代对象添加元素 
arr = array('i',range(4))
arr.extend(range(10))
arr
array('i', [0, 1, 2, 3, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
-------------------------------------------------------------------------
##fromlist   从一个列表中添加元素
l1  = list(range(5,10))
arr = array('i',range(4))
arr
array('i', [0, 1, 2, 3])
l1
[5, 6, 7, 8, 9]
arr.fromlist(l1)
arr
array('i', [0, 1, 2, 3, 5, 6, 7, 8, 9])
-------------------------------------------------------------------------
##  reverse 倒序一下,反转一下
arr
array('i', [0, 1, 2, 3, 5, 6, 7, 8, 9])

arr.reverse()
arr
array('i', [9, 8, 7, 6, 5, 3, 2, 1, 0])
-------------------------------------------------------------------------
## tolist 会根据array 的元素 返回一个list 
arr = array('i', [1, 2, 3, 4, 1, 11, 1, 22, 1, 2, 0, 1, 2, 1, 4])
arr.tolist()
[1, 2, 3, 4, 1, 11, 1, 22, 1, 2, 0, 1, 2, 1, 4]
-------------------------------------------------------------------------
# array.frombytes(s)  # 可以通过bytes 还原 array 对象  
# array.tobytes()  # 可以把array 转成 bytes 的表示

def test_frombytes_tobytes():
    arr = array('i', [1, 2, 11, 1, 220, 12, 1, 4])
    arr_bytes = arr.tobytes()
    print(arr_bytes)

    arr2 = array('i')
    arr2.frombytes(arr_bytes)
    print(arr2)

# 结果如下
Connected to pydev debugger (build 173.4127.16)
b'\x01\x00\x00\x00\x02\x00\x00\x00\x0b\x00\x00\x00\x01\x00\x00\x00\xdc\x00\x00\x00\x0c\x00\x00\x00\x01\x00\x00\x00\x04\x00\x00\x00'
array('i', [1, 2, 11, 1, 220, 12, 1, 4])
-------------------------------------------------------------------------
#  fromfile, tofile 这两个方法
array.fromfile(f, n)

# n 这个参数就是要读f读取多少个元素, 如果n> file中的个数 会报异常. 
EOFError: read() didn't return enough bytes

array.tofile(f)
Write all items (as machine values) to the file object f.
# 这个方法就是把array 对象写到文件中. 

# 简单的一个例子
from array import array

if __name__ == '__main__':
    arr = array('i', [1, 2, 11, 1, 220, 12, 1, 4])
    # 注意这里要二进制方式打开wb
    with open('arr.bin', 'wb') as f:
        arr.tofile(f)

    arr3 = array('i')
    print(arr3)
    # 注意这里要二进制方式打开
    with open('arr.bin', 'rb') as f:
        arr3.fromfile(f, 8)
    print(arr3)

# result :
Connected to pydev debugger (build 173.4127.16)
array('i')
array('i', [1, 2, 11, 1, 220, 12, 1, 4])
-------------------------------------------------------------------------

array创建的数组不适用于数字操作(比如矩阵和矢量运算)。另外+=和*=运算符可以用于array的添加。

从python3.4开始,数组(array)类型不再支持诸如list.sort()这种就地排序方法。要给数组排序的话,得用sorted函数新建一个数组:

>>> import array
>>> a = array.array(a.typecode, sorted(a))

array 与内置list 有什么区别?

array 可以紧凑地表示一个基本值的数组:字符,整数,浮点数。数组是序列类型,表现得非常像列表,除了存储在它们中的对象的类型是受约束的。

1.首先array 是数组, 数组是只能够保存一种类型的数, 初始化的时候就决定了可以保存什么样的数. 而list 里面 几乎可以放任何对象,已经类型,无论是数字,还是字典,还是对象,还是列表,都可以同时放到一个列表里面.

2.array 和list 提供的方法很多是相似的, 比如 append, insert ,pop extend, index,等等

参考:https://www.cnblogs.com/haoqirui/p/9977031.html https://blog.csdn.net/u010339879/article/details/81588215

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

扫码关注云+社区

领取腾讯云代金券