python列表元组字典集合

Python序列类似于其他语言中的数组,但功能要强大很多。

Python中常用的序列结构有列表、元组、字符串,字典、集合以及range等对象也支持很多类似的操作。

列表、元组、字符串支持双向索引,第一个元素下标为0,第二个元素下标为1,以此类推;最后 一个元素下标为-1,倒数第二个元素下标为-2,以此类推。

python 常见序列对比:

比较项列表元组字典集合
类型名称listtupledictset
定界符方括号[]圆括号()大括号{}大括号 {}
是否可变
是否有序
是否支持下标是(使用序号作为 下标)是(使用序号作 为下标)是(使用“键”作为下标)
元素分隔符逗号逗号逗号逗号
对元素形式的要求键:值必须可哈希
对元素值的要求必须可哈希必须可哈希
元素是否可重复“键”不允许重 复,“值”可以重复
元素查找速度非常慢很慢非常快非常快
新增和删除元素速度尾部操作快,其他位置慢不允许

列表

  • 列表是Python中内置有序、可变序列,列表的所有元素放在一对中括号“[]”中,并使用逗号分 隔开;
  • 当列表元素增加或删除时,列表对象自动进行扩展或收缩内存,保证元素之间没有缝隙;
  • 在Python中,一个列表中的数据类型可以各不相同,可以同时分别为整数、实数、字符串等基 本类型,甚至是列表、元组、字典、集合以及其他自定义类型的对象。

列表常用方法:

方法说明
lst.append(x)将元素x添加至列表lst尾部
lst.extend(L)将列表L中所有元素添加至列表lst尾部
lst.insert(index, x)在列表lst指定位置index处添加元素x,该位置后面的所有元素后移 一个位置
lst.remove(x)在列表lst中删除首次出现的指定元素,该元素之后的所有元素前移一 个位置
lst.pop([index])删除并返回列表lst中下标为index(默认为-1)的元素
lst.clear()删除列表lst中所有元素,但保留列表对象
lst.index(x)返回列表lst中第一个值为x的元素的下标,若不存在值为x的元素则 抛出异常
lst.count(x)返回指定元素x在列表lst中的出现次数
lst.reverse()对列表lst所有元素进行逆序
lst.sort(key=None, reverse=False)对列表lst中的元素进行排序,key用来指定排序依据,reverse决定 升序(False)还是降序(True)
lst.copy()返回列表lst的浅复制
  • lst.reverse(),lst.sort()

    >>> arr = list(range(10))
    >>> arr
    [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
    >>> arr.reverse()					#逆序
    >>> arr 	
    [9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
    >>> arr.sort()						#排序
    >>> arr
    [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
    

浅复制,浅层次的复制,深复制

>>> arr = [1,2,3]
>>> arr = [1,2,3]
>>> arr1 = arr                   # 直接赋值 arr 和 arr1 共用内存  也就是说他们还是一个
>>> id(arr),id(arr1)
(2909054945928, 2909054945928)
>>> arr1[0] = 123
>>> arr                          #修改一个另一个也会改变
[123, 2, 3]
>>> arr2 = arr.copy()            #浅复制,
>>> id(arr),id(arr2)             #不共用内存了
(2909054945928, 2909053356424)   
>>> arr2[0]=321					#修改一个另一个不会改变
>>> arr
[123, 2, 3]
>>> arr = [[1],2,3]				#但是列表里面有可变序列时,可变序列改变 原来的也会改变
>>> arr2 = arr.copy()
>>> arr2[0].append(2)
>>> arr							#在arr2里添加,arr里面也有了
[[1, 2], 2, 3]
>>> import copy					#标准库copy
>>> arr
[[1, 2], 2, 3]
>>> arr3 = copy.deepcopy(arr)    #深复制
>>> arr3
[[1, 2], 2, 3]          
>>> arr3[0].pop() 					#arr3内层序列改变  arr不受影响
2
>>> arr								
[[1, 2], 2, 3]

列表的索引:

  • 下标索引
>>> arr = list(range(20))
>>> arr
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]
>>> arr[2]
2
>>> arr[0]
0
>>> arr[-2]   #可以双向来
18
  • 切片
    • 切片适用于列表、元组、字符串、range对象等类型,但作用于列表时功能强大。可以使用切片来截取列表中的任何部分,得到一个新列表,也可以通过切片来修改和删除列表中部分元素,甚至可以通过切片操作为列表对象增加元素。
    • 切片使用2个冒号分隔的3个数字来完成:[start: end: step]
      1. 第一个数字表示切片开始位置(默认为0)。
      2. 第二个数字表示切片截止(但不包含)位置(默认为列表长度)。
      3. 第三个数字表示切片的步长(默认为1),当步长省略时可以顺便省略后一个冒号
    • 切片操作不会因为下标越界而抛出异常,而是简单地在列表尾部截断或者返回一个空列表,代码具有更强的健壮性。
>>> lit = list(range(5))
>>> lit
[0, 1, 2, 3, 4]
>>> lit[1:]
[1, 2, 3, 4]
>>> lit[:3]
[0, 1, 2]
>>> lit[:-3]
[0, 1]
>>> lit[1::2]
[1, 3]
>>> lit[:3:2]
[0, 2]
>>> lit[1::2]=[111,111]
>>> lit							#可以使用切片来原地修改列表内容
[0, 111, 2, 111, 4]

>>> lit2 = lit[::]              #切片返回的是列表元素的浅复制
>>> lit2
[0, 111, 2, 111, 4]
>>> lit2[1]=222
>>> lit
[0, 111, 2, 111, 4]
>>> lit2
[0, 222, 2, 111, 4]

列表推导式

列表推导式使用非常简洁的方式来快速生成满足特定需求的列表,代码具有非常强的可读性。

列表推导式语法形式为:
[expression for expr1 in sequence1 if condition1
            for expr2 in sequence2 if condition2
            for expr3 in sequence3 if condition3
            ...
            for exprN in sequenceN if conditionN]

列表推导式在内部实际上是一个循环结构,只是形式更加简洁,例如:

>>> aList = [x*x for x in range(10)]
>>> aList
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]

使用列表推导式实现嵌套列表的平铺:

>>> vec = [[1,2,3], [4,5,6], [7,8,9]] 
>>> [num for elem in vec for num in elem] 
[1, 2, 3, 4, 5, 6, 7, 8, 9] 

再如取偶数:

>>> arr = list(range(10))
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> [i for i in arr if i%2==0]
[0, 2, 4, 6, 8]
>>> [i for i in range(30) if i%2==0]
[0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28]

元组

  • 元组和列表类似,但属于不可变序列,元组一旦创建,用任何方法都不可以修改其元素。

  • 元组的定义方式和列表相同,但定义时所有元素是放在一对圆括号“()”中,而不是方括号中。

    列表和元组的区别

    1. 列表是动态数组,他们可变且可以重设长度(改变其内部元素的个数)。
    2. 元组是静态数组,他们不可变,且其内部数据一旦创建便无法改变。
    3. 元组缓存与Python运行时环境,这意味着我们每次使用元组时无须动态访问内核去分配内存。

    列表和元组都可以接受混合类型。

    >>> t = tuple(range(5))
    >>> t
    (0, 1, 2, 3, 4)
    >>> t[1]=22
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    TypeError: 'tuple' object does not support item assignment
    

生成器推导式

生成器推导式的结果是一个生成器对象。使用生成器对象的元素时,可以根据需要将其转化为列表或元组,也可以使用生成器对象__next__()方法或内置函数next()进行遍历,或者直接将其作为迭代器对象来使用。

生成器对象具有惰性求值的特点,只在需要时生成新元素,比列表推导式具有更高的效率,空间占用非常少,尤其适合大数据处理的场合。

不管用哪种方法访问生成器对象,都无法再次访问已访问过的元素。

>>> g = (i for i in range(10))
>>> next(g)
0
>>> next(g)
1
>>> g.__next__()
2
>>> list(g)
[3, 4, 5, 6, 7, 8, 9]
>>> g = (i for i in range(10))
>>> 5 in g    #找到5时 3已经遍历过了  所以 下面找不到3
True
>>> 3 in g    #但会继续往下找  直到遍历了所有的元素
False
>>> 6 in g    #所有6也在上次查找时被遍历了
False
>>> g = (i for i in range(10))
>>> 3 in g
True
>>> 5 in g
True

补充序列解包

序列解包是Python中非常重要和常用的一个功能,可以使用非常简洁的形式完成复杂的功能,提高了代码可读性,减少了代码输入量。

  • 可以使用序列解包功能对多个变量同时赋值
>>> x, y, z = 1, 2, 3
>>> print(x,y,z)
1 2 3
>>> v_tuple = (4, 5, 6)
>>> x, y, z = v_tuple
>>> print(x,y,z)
4 5 6
>>> x, y, z = range(7,10)
>>> print(x,y,z)
7 8 9
  • 更多的使用
>>> x, y, z = range(3)            #可以对range对象进行序列解包
>>> x, y, z = iter([1, 2, 3])     #使用迭代器对象进行序列解包
>>> x, y, z = map(str, range(3))  #使用可迭代的map对象进行序列解包
>>> a, b = b, a                   #交换两个变量的值
>>> x, y, z = sorted([1, 3, 2])   #sorted()函数返回排序后的列表
>>> a, b, c = 'ABC'               #字符串也支持序列解包
>>> x = [1, 2, 3, 4, 5, 6]
>>> x[:3] = map(str,range(5))     #切片也支持序列解包
>>> x
['0', '1', '2', '3', '4', 4, 5, 6]
  • 序列解包遍历多个序列
>>> keys = ['a', 'b', 'c', 'd']
>>> values = [1, 2, 3, 4]
>>> for k, v in zip(keys, values):
	  print((k, v), end=' ')

('a', 1) ('b', 2) ('c', 3) ('d', 4) 
  • 对字典也适用
>>> s = {'a':1, 'b':2, 'c':3}
>>> b, c, d = s.items()
>>> b
('c', 3)
>>> b, c, d = s
>>> b
'c'
>>> b, c, d = s.values()
>>> print(b, c, d)
1 3 2

字典

  • 字典是无序、可变序列。

  • 定义字典时,每个元素的键和值用冒号分隔,元素之间用逗号分隔,所有的元素放在一对大括号“{}”中。

  • 字典中的键可以为任意不可变数据,比如整数、实数、复数、字符串、元组等等。

    • globals()返回包含当前作用域内所有全局变量和值的字典
    • locals()返回包含当前作用域内所有局部变量和值的字典

    创建:

    >>> a_dict = {'one':1,'two':2,'three':3}
    >>> a_dict
    {'one': 1, 'two': 2, 'three': 3}
    >>> keys = list('abcde')
    >>> values = list(range(4))
    >>> dictionary = dict(zip(keys,values))
    >>> dictionary
    {'a': 0, 'b': 1, 'c': 2, 'd': 3}
    >>> x = dict()
    >>> x          #空字典
    {}
    >>> d = dict(name='Dong', age=37)    #使用键值创建字典
    >>> d
    {'name': 'Dong', 'age': 37}
    >>> adict = dict.fromkeys(['name','age','sex'])   #给定内容创建字典,值为空
    >>> adict
    {'name': None, 'age': None, 'sex': None}
    

    读取:

    >>> a_dict = {'one':1,'two':2,'three':3}
    >>> a_dict['one']     #根据键获取值
    1
    >>> a_dict['name']
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    KeyError: 'name'
    

    使用字典对象的get方法获取指定键对应的值,并且可以在键不存在的时候返回指定值

    >>> a_dict.get('one')
    1
    >>> a_dict.get('name','None')  #如果不存在 返回给定值
    'None'
    

    使用字典对象的items()方法可以返回字典的键、值对

    使用字典对象的keys()方法可以返回字典的键

    使用字典对象的values()方法可以返回字典的值

    >>> for k,g in a_dict.items():  #序列解包 
    ...     print(k)
    ...     print(g)
    ...
    one
    1
    two
    2
    three
    3
    >>> a_dict.keys()
    dict_keys(['one', 'two', 'three'])
    

    添加,修改

    当以指定键为下标为字典赋值时:

    1)若键存在,则可以修改该键的值;

    2)若不存在,则表示添加一个键、值对。

    >>> a_dict
    {'one': 1, 'two': 2, 'three': 3}
    >>> a_dict['one'] = 11     #修改
    >>> a_dict
    {'one': 11, 'two': 2, 'three': 3}
    >>> a_dict['four'] = 4     #添加
    >>> a_dict
    {'one': 11, 'two': 2, 'three': 3, 'four': 4}
    

    使用字典对象的update()方法将另一个字典的键、值对添加到当前字典对象。

    >>> a_dict
    {'one': 11, 'two': 2, 'three': 3, 'four': 4}
    >>> b_dict = {'five': 5}
    >>> a_dict.update(b_dict)  #将b_dict加到a_dict中
    >>> a_dict
    {'one': 11, 'two': 2, 'three': 3, 'four': 4, 'five': 5}
    
    • 使用del删除字典中指定键的元素
    • 使用字典对象的clear()方法来删除字典中所有元素
    • 使用字典对象的pop()方法删除并返回指定键的元素
    • 使用字典对象的popitem()方法删除并返回字典中的一个元素

    字典推导式

    >>> s = {str(x):x for x in range(4)}
    >>> s
    {'0': 0, '1': 1, '2': 2, '3': 3}
    

    注意 : 字典的键是可以哈希的,且键都是唯一的。不能为可变元素,如:列表。

集合

  • 集合是无序、可变序列,使用一对大括号界定,元素不可重复,同一个集合中每个元素都是唯一的。

  • 集合中只能包含数字、字符串、元组等不可变类型(或者说可哈希)的数据,而不能包含列表、字典、集合等可变类型的数据。

    简单说集合就是没有值的字典。

    >>> a = {3, 5}
    >>> a
    {3, 5}
    >>> a.add(4)
    >>> a
    {3, 4, 5}
    >>> a = {3,3,2,4,4}
    >>> a
    {2, 3, 4}
    >>> set(range(3,8))
    {3, 4, 5, 6, 7}
    >>> set()
    set()
    
    • 当不再使用某个集合时,可以使用

      del命令删除整个集合。集合对象的

      pop()方法弹出并删除其中一个元素

      remove()方法直接删除指定元素,

      clear()方法清空集合。

      >>> a = {1,2,3,4}
      >>> a.pop()
      1
      >>> a.pop()
      2
      >>> a
      {3, 4}
      >>> a.add(2)
      >>> a
      {2, 3, 4}
      >>> a.remove(3)
      >>> a
      {2, 4}
      >>> a.clear()
      >>> a
      set()
      >>> del a
      >>> a
      Traceback (most recent call last):
        File "<stdin>", line 1, in <module>
      NameError: name 'a' is not defined
      

      Python集合支持交集,并集,差集等运算

      >>> a_set = set(range(8,14))
      >>> b_set = set(range(9))
      >>> a_set | b_set						#并集
      {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13}
      >>> a_set.union(b_set)
      {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13}
      >>> a_set & b_set						#交集
      {8}
      >>> a_set.intersection(b_set)
      {8}
      >>> a_set - b_set						#差集
      {9, 10, 11, 12, 13}
      >>> a_set.difference(b_set)
      {9, 10, 11, 12, 13}
      >>> {3} & {4}
      set()
      >>> {3}.isdisjoint({4})                #如果两个集合的交集为空,返回True
      True
      >>> x^y								#对称差
      {3, 5}
      >>> x.symmetric_difference(y)
      {3, 5}
      

      子集,真子集,包含

      >>> x = {1, 2, 3}
      >>> y = {1, 2, 5}
      >>> z = {1, 2, 3, 4}
      >>> x.issubset(y)                      #测试是否为子集
      False
      >>> x.issubset(z)
      True
      >>> x < y                                #比较集合大小/包含关系
      False
      >>> x < z                                #真子集
      True
      >>> y < z
      False
      >>> {1, 2, 3} <= {1, 2, 3}               #子集
      True
      
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值