python编程基础——基本数据类型之列表


Python内置的数据类型列表(list)是一个可变的对象序列。在python中我们一般不区分列表和数组,(其他语言中则需要区分,因为数组长度是固定的,不支持插入和删除。下文中若无特殊说明数组和列表等价)我们使用列表作为数组除了实现数组的基本功能外,python列表还允许插入元素和删除元素。你也可以把列表理解为是一种高级的数组。
list中的元素是任意类型的, 可以是int、 str, 还可以是list, 甚至是dict等。

基本操作

a=[3,6,7,9,10,4]
b=[2,5,1]

基本操作
量级 操作 结果 描述
常量 len(a) 6 列表a的长度
常量 a[4] 10 列表a的第4项(索引访问操作)
常量 a[4]=9 9 列表a的第4项替换成9(索引赋值操作)
常量 a.pop()1 4 相当于出栈
线性 a+b [3, 6, 7, 9, 10, 4, 2, 5, 1] 列表a和b拼接
线性 a[2:5] [7,9,10] 切片操作
线性 a[2:5]=b2 [3, 6, 2, 5, 1, 4] 将a的切片部分替换为b
线性 min(a) 3 最小项
线性 max(a) 10 最大项
线性 sum(a) 39 求和
线性 4 in a True 若包含则为True,不包含则为False(包含操作)
常量 b+=[6] [2,5,1,6] 将6附加到b的尾部(就地拼接操作)
线性 del b[1]3 [2,1] 从列表中删除b[1](索引删除操作)
线性 b.insert(2,9) [2, 5, 9, 1] (指定位置插入) 将9插入到a[2]的前面,单次仅运行插入一个元素
线性 b.reverse() [1, 5, 2] 列表a中的各项反序
线性 b.sort [1,2,5] 将列表a中各项升序排序
线性 a.index(7) 2 项7第一次出线在列表a中的索引号

可变数组

可变数组是一个存储一系列数据项的不定长度的数据结构,可以通过索引下标访问各项数据元素。

在实现方面,当用户创建一个可变数组时,python先创建一个固定长度n的数组。在内存中以n为大小划分连续内存单元,用于存储各项数据的内存地址(即引用)。那么我们怎么知道一个数组用于引用所使用的空间占用了连续分配空间的多少呢?这里我们使用属于大小(size)表示所使用的个数容量(capacity)表示n的大小。例如python为a=[4,3,5]划分了10个连续的内存单元,那么size=3,capacity=10。

当size==capacity时,表示当前所划分的连续内存单元被占满,这时则创建一个长度是原来两倍容量大小的连续内存单元,并将旧数据复制过来。反之若size<=capacity/2时,则创建一个capacity=capacity/2大小的连续内存空间,并将旧数据复制过来。这样就能最大限度保证内存单元得到充分利用。(当然本文提到的扩容压缩实际使用的倍数可能不同,但原理是一样的。)


下图显示的是可变数组在随着引用的增加而进行2倍扩容:
example

索引和切片

先来回顾一下字符串的索引和切片

>>> str="asdqwe"
>>> str[2]
'd'
>>> str[:3]
'asd'
>>> str[:-3]
'asd'
>>> str[1:3]
'sd'

在Python中,因为列表和字符串的内存存储上很相似,所以在索引和切片上也很相似。
索引数字从左边开始编号,第一个是0,然后依次增加1。此外还有一种编号方式是从右边开始,右边第一个编号为-1,然后依次是-2,-3,…,依次类推

>>> a=['a',123,'asdqwe']
>>> a[1]
123
>>> a[:2]
['a', 123]
>>> a[1:]
[123, 'asdqwe']
>>> a[:-1]
['a', 123]

序列的切片, 一定要左边的数字小于右边的数字,否则返回的是一个空。

反转

[::-1]反转

反转在编程中常常会用到。值得一提的是反转后原来的值并没有改变。

>>> a=[1,2,3,4,5,6]
>>> a[::-1]
[6, 5, 4, 3, 2, 1]
>>> b="123456"
>>> b[::-1]
'654321'

reversed()反转

# 它返回一个可以迭代的对象
>>> reversed(a)
<list_reverseiterator object at 0x000002983B1AFE10>

# a的值不改变
>>> list(reversed(a))
[6, 5, 4, 3, 2, 1]
>>> list(reversed(b))
['6', '5', '4', '3', '2', '1']

# a的值改变
>>> a.reverse()
>>> a
[3, 5, 4, 3, 2, 1]


添加和删除

append()和a[len(a):]=[x]追加

append()和a[len(a):]=[x]追加是一个意思,都是在最后添加一个元素

>>> a
[3, 5, 4, 3, 2, 1]
>>> a.append(9)
>>> a
[3, 5, 4, 3, 2, 1, 9]
>>> a[len(a):]=[7]
>>> a
[3, 5, 4, 3, 2, 1, 9, 7]

extend()和a[len(a):]=L追加

extend()和a[len(a):]=L追加是一个意思,都是在最后添加一个列表

>>> a=[1,2,3]
>>> b=[1,1,1]
>>> a.extend(b)
>>> a
[1, 2, 3, 1, 1, 1]

extend()和append()的区别

对于extend()是在列表的最后接上另一个列表,对于append()则是在列表最后添加一个新的元素。可以从下面看出两者的不同区别。

>>> a=[1,2,3]
>>> b=[1,1,1]
>>> c="asd"
>>> a.append(b)
>>> a
[1, 2, 3, [1, 1, 1]]
>>> a.extend(b)
>>> a
[1, 2, 3, [1, 1, 1], 1, 1, 1]
>>> a.extend(c)
>>> a
[1, 2, 3, [1, 1, 1], 1, 1, 1, 'a', 's', 'd']
>>> a.append(c)
>>> a
[1, 2, 3, [1, 1, 1], 1, 1, 1, 'a', 's', 'd', 'asd']
>>> a.extend(3)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'int' object is not iterable

extend的对象是一个list,如果是str,则Python会先把它按照
字符为单位转化为list再追加到已知list。append的对象数据类型无要求。

扫描二维码关注公众号,回复: 8486956 查看本文章

pop和remove删除

  • list.remove(x)
    Remove the first item from the list whose value is x.It is an error if there
    is no such item.
  • list.pop([i])
    Remove the item at the given position in the list,and return it.If no
    index is specified,a.pop()removes and returns the last item in the list.(The
    square brackets around the i in the method signature denote that the
    parameter is optional,not that you should type square brackets at that
    position.You will see this notation frequently in the Python Library
    Reference.)

可以看出pop和remove都是删除列表中的元素,不同的是pop是通过索引来删除

>>> a=[1,2,3,4,5]
>>> a.remove(2)
>>> a
[1, 3, 4, 5]
>>> a.remove(2)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: list.remove(x): x not in list

>>> a=[1,2,3,4,5]
>>> a.pop(2)
3
>>> a
[1, 2, 4, 5]
>>> a.pop()
5
>>> a
[1, 2, 4]

插入

python中提供了insert(i,x)函数,这个函数有里那个参数,即在a[i]前插入x。

>>> a=[1,2,3]
>>> a.insert(1,7)
>>> a
[1, 7, 2, 3]

如果insert的插入位置超出了列表a的索引位置时,该如何插入呢?如果遇到那个i已经超过了最大索引值,会自动将所要
插入的元素放到列表的尾部,即追加。
如果插入的位置i为负时,则在倒是第| i |个位置前插入值。

>>> a.insert(9,5)
>>> a
[1, 7, 2, 3, 5]
>>> a.insert(-2,5)
>>> a
[1, 7, 2, 5, 3, 5]


排序

sort是对列表进行排序。默认是从小到大排序,当reverse=True时,为从大到小排序。
我们先来看一下开发文档是怎么说的:

>>> help(list.sort)
Help on method_descriptor:

sort(self, /, *, key=None, reverse=False)
    Stable sort *IN PLACE*.

其中 “ / ” 是使用位置 , “ * “ 表示使用关键字

  • 使用位置-仅当名称不重要或没有意义,并且只有少数参数将始终以相同的顺序传递。
  • 使用关键字-仅当名称有意义时,而函数定义通过对名称的显式定义更容易理解。
>>> a=[9,3,4,6]
>>> a.sort()
>>> a
[3, 4, 6, 9]
>>> a.sort(reverse=True)
>>> a
[9, 6, 4, 3]

关于sorted可以参见史上最全关于sorted函数的10条总结

列表和字符串的相互转化

str.split()

这个内置函数是将str以指定的分割字符切分字符串为列表,我们先看一下函数说明:

split(sep=None, maxsplit=-1) method of builtins.str instance
    Return a list of the words in the string, using sep as the delimiter string.

    sep
      The delimiter according which to split the string.
      None (the default value) means split according to any whitespace,
      and discard empty strings from the result.
    maxsplit
      Maximum number of splits to do.
      -1 (the default value) means no limit.

简言之,在str.split()函数中,有两个参数,第一个就是分割符,用于拆分字符串的分隔符。默认表示根据任何空格进行拆分, 并从结果中丢弃空字符串。第二个是分割块数。默认是最大分隔块数。

>>> str="helllo,world"
>>> str.split(",")
['helllo', 'world']
>>> str.split("l",1)
['he', 'llo,world']
>>> str.split("l",4)
['he', '', '', 'o,wor', 'd']
#使用默认值进行分割
>>> s = "I am, writing\npython\tbook on line"
>>> s.split()
['I', 'am,', 'writing', 'python', 'book', 'on', 'line']

" ".join()

如果说split()是将string转化为list,那么join就是将string转化为string。join可以说是split的逆运算。

>>> str
['using', 'sep', 'as', 'the', 'delimiter.']
>>> " ".join(str)
'using sep as the delimiter.'
>>> "-".join(str)
'using-sep-as-the-delimiter.'

多维列表

在列表中,元素可以是任何类型,因此列表也可以由列表组成,这样就构成了二维列表,三维列表…

>>> a=[[1,2,3],[4,5,6],[7,8,9]]
>>> a[2][1]
8


列表解析

列表解析是一个非常有意思的功能,列表解析为创建列表提供了一种简洁的方法。常见的应用是创建新列表,其中每个元素是应用于另一个序列的每个成员或可迭代的某些操作的结果,或者创建满足特定条件的那些元素的子序列。

>>> squares = [x**2 for x in range(1,10)]
>>> squares
[1, 4, 9, 16, 25, 36, 49, 64, 81]
>>> s = [str(x) for x in squares]
>>> s
['1', '4', '9', '16', '25', '36', '49', '64', '81']

  1. 默认值是栈顶,且一次仅允许出栈一个元素,如果想pop出a[i],则只需a.pop(i),如a.pop(4),结果为[3, 6, 7, 9, 4] ↩︎

  2. a切片部分和b一定要满足相等的关系吗?当然不是,例如:a[2:4]=b,替换后a=[3, 6, 2, 5, 1, 10, 4],那a[i:i]=b能运行吗?令人惊奇的是可以 例如,a[2:2]在a[1]和a[2]间插入了b,结果为[3, 6, 2, 5, 1, 7, 9, 10, 4] ↩︎

  3. del可以用于删除指定位置的某一段索引例如del a[2:4]=[3,6,10,4]。值得注意的是del b[:] 仅仅是删除了b中的索引并没有删掉b这个列表,此时的输出结果是 [ ],而del b则是删除整个列表,此时如果再输出b则会报错 name ‘b’ is not defined↩︎

发布了19 篇原创文章 · 获赞 19 · 访问量 3621

猜你喜欢

转载自blog.csdn.net/qq_36733722/article/details/86501203