代码改变世界

python 数据结构

2022-04-05 16:45  jym蒟蒻  阅读(59)  评论(0编辑  收藏  举报
  • python 列表、元组、集合、字典、数据结构的循环(整理自python文档)
    • 列表-list-用方括号标注,逗号分隔的一组值
      • list 的 方法
        • 对list添加、插入、删除、查找、排列、翻转
        • list.append(x)
        • list.extend(iterable)
        • list.insert(i, x)
        • list.remove(x)
        • list.pop([i])
        • list.clear()
        • list.index(x[, start[, end]])
        • list.count(x)
        • list.sort(*, key=None, reverse=False)
        • list.reverse()
        • list.copy()
      • list 实现堆栈-append和pop
      • list 实现队列
      • 创建list
      • 列表推导式创建list
      • 嵌套的列表推导式
    • del语句
      • del-从列表中移除元素、移除切片、清空列表
      • del-删除变量
    • 元组和序列-多个用逗号隔开的值
      • 元组的格式-圆括号
      • 元组和列表-不可变 与 可变
      • 创建元组
      • 元组序列解包
    • 集合-由不重复元素组成的无序容器。
      • 创建集合-用花括号或 `set() ` 函数
    • 字典
      • 字典的索引(键)-不可变类型
      • 字典的键-唯一
      • 创建字典
      • 字典的主要用途-通过关键字存储、提取值
    • 数据结构的循环
      • 字典中循环-取出键和值-items()
      • 序列中循环-取出位置和值-enumerate()
      • 循环多个序列-元素匹配-zip()
      • 逆向循环-reversed()
      • 指定顺序循环序列-sorted()
      • 循环遍历序列中的唯一元素-set()
      • 循环中修改列表的内容-创建新列表

 

python 列表、元组、集合、字典、数据结构的循环(整理自python文档)

列表-list-用方括号标注,逗号分隔的一组值

列表 ,是用方括号标注,逗号分隔的一组值。可以包含不同类型的元素,也支持索引和切片。

列表数据类型支持很多方法,列表对象的所有方法所示如下:

list 的 方法

对list添加、插入、删除、查找、排列、翻转

list.append(x)

在列表末尾添加一个元素,相当于 a[len(a):] = [x] 。

list.extend(iterable)

用可迭代对象的元素扩展列表。相当于 a[len(a):] = iterable 。

list.insert(i, x)

在指定位置插入元素。第一个参数是插入元素的索引,因此,a.insert(0, x) 在列表开头插入元素, a.insert(len(a), x) 等同于 a.append(x) 。

list.remove(x)

从列表中删除第一个值为 x 的元素。未找到指定元素时,触发 ValueError 异常。

list.pop([i])

删除列表中指定位置的元素,并返回被删除的元素。未指定位置时,a.pop() 删除并返回列表的最后一个元素。(方法签名中 i 两边的方括号表示该参数是可选的,不是要求输入方括号。这种表示法常见于 Python 参考库)。

list.clear()

删除列表里的所有元素,相当于 del a[:] 。

list.index(x[, start[, end]])

返回列表中第一个值为 x 的元素的零基索引。未找到指定元素时,触发 ValueError 异常。

可选参数 start 和 end 是切片符号,用于将搜索限制为列表的特定子序列。返回的索引是相对于整个序列的开始计算的,而不是 start 参数。

list.count(x)

返回列表中元素 x 出现的次数。

list.sort(*, key=None, reverse=False)

就地排序列表中的元素(要了解自定义排序参数,详见 sorted())。

list.reverse()

翻转列表中的元素。

list.copy()

返回列表的浅拷贝。相当于 a[:] 。

>>> fruits = ['orange', 'apple', 'pear', 'banana', 'kiwi', 'apple', 'banana']
>>> fruits.count('apple')
2
>>> fruits.count('tangerine')
0
>>> fruits.index('banana')
3
>>> fruits.index('banana', 4)  # Find next banana starting a position 4
6
>>> fruits.reverse()
>>> fruits
['banana', 'apple', 'kiwi', 'banana', 'pear', 'apple', 'orange']
>>> fruits.append('grape')
>>> fruits
['banana', 'apple', 'kiwi', 'banana', 'pear', 'apple', 'orange', 'grape']
>>> fruits.sort()
>>> fruits
['apple', 'apple', 'banana', 'banana', 'grape', 'kiwi', 'orange', 'pear']
>>> fruits.pop()
'pear'

insert、remove、sort 等方法只修改列表,不输出返回值——返回的默认值为 None 。

不是所有数据都可以排序或比较。例如,[None, ‘hello’, 10] 就不可排序,因为整数不能与字符串对比,而 None 不能与其他类型对比。

list 实现堆栈-append和pop

使用列表方法实现堆栈,最后插入的最先取出(“后进先出”)。

把元素添加到堆栈的顶端,使用 append() 。

从堆栈顶部取出元素,使用 pop()

>>> stack = [3, 4, 5]
>>> stack.append(6)
>>> stack.append(7)
>>> stack
[3, 4, 5, 6, 7]
>>> stack.pop()
7
>>> stack
[3, 4, 5, 6]
>>> stack.pop()
6
>>> stack.pop()
5
>>> stack
[3, 4]

list 实现队列

列表也可以用作队列,最先加入的元素,最先取出(“先进先出”)。

列表作为队列的效率很低。因为,在列表末尾添加和删除元素非常快,但在列表开头插入或移除元素却很慢(因为所有其他元素都必须移动一位)

实现队列最好用 [collections.deque],可以快速从两端添加或删除元素

>>> from collections import deque
>>> queue = deque(["Eric", "John", "Michael"])
>>> queue.append("Terry")           # Terry arrives
>>> queue.append("Graham")          # Graham arrives
>>> queue.popleft()                 # The first to arrive now leaves
'Eric'
>>> queue.popleft()                 # The second to arrive now leaves
'John'
>>> queue                           # Remaining queue in order of arrival
deque(['Michael', 'Terry', 'Graham'])

创建list

对序列或可迭代对象中的每个元素应用某种操作,用生成的结果创建新的列表。

例如,创建平方值的列表:

>>> squares = []
>>> for x in range(10):
...     squares.append(x**2)
...
>>> squares
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]

列表推导式创建list

squares = [x**2 for x in range(10)]

列表推导式的方括号内包含以下内容:

一个表达式,后面为一个 for 子句,然后,是零个或多个 for 或 if 子句。

结果是由表达式依据 for 和 if 子句求值计算而得出一个新列表。

>>> [(x, y) for x in [1,2,3] for y in [3,1,4] if x != y]
[(1, 3), (1, 4), (2, 3), (2, 1), (2, 4), (3, 1), (3, 4)]

等价于:

>>> combs = []
>>> for x in [1,2,3]:
...     for y in [3,1,4]:
...         if x != y:
...             combs.append((x, y))
...
>>> combs
[(1, 3), (1, 4), (2, 3), (2, 1), (2, 4), (3, 1), (3, 4)]

其他例子:

>>> vec = [-4, -2, 0, 2, 4]
>>> # create a new list with the values doubled
>>> [x*2 for x in vec]
[-8, -4, 0, 4, 8]




>>> # filter the list to exclude negative numbers
>>> [x for x in vec if x >= 0]
[0, 2, 4]




>>> # apply a function to all the elements
>>> [abs(x) for x in vec]
[4, 2, 0, 2, 4]



>>> # call a method on each element
>>> freshfruit = ['  banana', '  loganberry ', 'passion fruit  ']
>>> [weapon.strip() for weapon in freshfruit]
['banana', 'loganberry', 'passion fruit']



>>> # create a list of 2-tuples like (number, square)
>>> [(x, x**2) for x in range(6)]
[(0, 0), (1, 1), (2, 4), (3, 9), (4, 16), (5, 25)]



>>> # the tuple must be parenthesized, otherwise an error is raised
>>> [x, x**2 for x in range(6)]
  File "<stdin>", line 1, in <module>
    [x, x**2 for x in range(6)]
               ^
SyntaxError: invalid syntax
    
    
    
>>> # flatten a list using a listcomp with two 'for'
>>> 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]




>>> from math import pi
>>> [str(round(pi, i)) for i in range(1, 6)]
['3.1', '3.14', '3.142', '3.1416', '3.14159']

嵌套的列表推导式

>>> matrix = [
...     [1, 2, 3, 4],
...     [5, 6, 7, 8],
...     [9, 10, 11, 12],
... ]

下面的列表推导式可以转置行列:

>>> [[row[i] for row in matrix] for i in range(4)]
[[1, 5, 9], [2, 6, 10], [3, 7, 11], [4, 8, 12]]

等价于:

>>> transposed = []
>>> for i in range(4):
...     # the following 3 lines implement the nested listcomp ,row是行的意思
...     transposed_row = []
...     for row in matrix:#matrix 有三行 
...         transposed_row.append(row[i])
...     transposed.append(transposed_row)
...
>>> transposed
[[1, 5, 9], [2, 6, 10], [3, 7, 11], [4, 8, 12]]

等价于:

>>> list(zip(*matrix))
[(1, 5, 9), (2, 6, 10), (3, 7, 11), (4, 8, 12)]

del语句

del-从列表中移除元素、移除切片、清空列表

[del]语句按索引,而不是值从列表中移除元素。与返回值的 pop() 方法不同, del 语句也可以从列表中移除切片,或清空整个列表(之前是将空列表赋值给切片)。

>>> a = [-1, 1, 66.25, 333, 333, 1234.5]
>>> del a[0]
>>> a
[1, 66.25, 333, 333, 1234.5]
>>> del a[2:4]
>>> a
[1, 66.25, 1234.5]
>>> del a[:]
>>> a
[]

del-删除变量

[del]也可以用来删除整个变量:

>>> del a

元组和序列-多个用逗号隔开的值

元组由多个用逗号隔开的值组成。

>>> t = 12345, 54321, 'hello!'
>>> t[0]
12345
>>> t
(12345, 54321, 'hello!')
>>> # Tuples may be nested:
... u = t, (1, 2, 3, 4, 5)
>>> u
((12345, 54321, 'hello!'), (1, 2, 3, 4, 5))
>>> # Tuples are immutable:
... t[0] = 88888
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'tuple' object does not support item assignment
>>> # but they can contain mutable objects:
... v = ([1, 2, 3], [3, 2, 1])
>>> v
([1, 2, 3], [3, 2, 1])

元组的格式-圆括号

输出时,元组都要由圆括号标注。

输入时,圆括号可有可无,不过经常是必须的(如果元组是更大的表达式的一部分)。

不允许为元组中的单个元素赋值,当然,可以创建含列表等可变对象的元组。

元组和列表-不可变 与 可变

元组与列表很像,但使用场景不同,用途也不同。

元组是 [immutable](不可变的),一般可包含异质元素序列,通过解包或索引访问。

列表是 [mutable] (可变的),列表元素一般为同质类型,可迭代访问。

创建元组

用一对空圆括号就可以创建空元组;只有一个元素的元组可以通过在这个元素后添加逗号来构建。

>>> empty = ()
>>> singleton = 'hello',    # <-- note trailing comma
>>> len(empty)
0
>>> len(singleton)
1
>>> singleton
('hello',)

元组序列解包

t = 12345, 54321, 'hello!' 是 元组打包 的例子:值 1234554321 和 'hello!' 一起被打包进元组。

序列解包 ,适用于右侧的任何序列。序列解包时,左侧变量与右侧序列元素的数量应相等。

>>> x, y, z = t

集合-由不重复元素组成的无序容器。

集合是由不重复元素组成的无序容器。

基本用法包括成员检测、消除重复元素。

集合对象支持合集、交集、差集、对称差分等数学运算。

创建集合-用花括号或 set() 函数

创建集合用花括号或 set() 函数。注意,创建空集合只能用 set(),不能用 {}{} 创建的是空字典。

>>> basket = {'apple', 'orange', 'apple', 'pear', 'orange', 'banana'}
>>> print(basket)                      # show that duplicates have been removed
{'orange', 'banana', 'pear', 'apple'}
>>> 'orange' in basket                 # fast membership testing
True
>>> 'crabgrass' in basket
False

>>> # Demonstrate set operations on unique letters from two words
...
>>> a = set('abracadabra')
>>> b = set('alacazam')
>>> a                                  # unique letters in a
{'a', 'r', 'b', 'c', 'd'}
>>> a - b                              # letters in a but not in b
{'r', 'd', 'b'}
>>> a | b                              # letters in a or b or both
{'a', 'c', 'r', 'd', 'b', 'm', 'z', 'l'}
>>> a & b                              # letters in both a and b
{'a', 'c'}
>>> a ^ b                              # letters in a or b but not both
{'r', 'd', 'b', 'm', 'z', 'l'}

与 [列表推导式]类似,集合也支持推导式:

>>> a = {x for x in 'abracadabra' if x not in 'abc'}
>>> a
{'r', 'd'}

字典

字典的索引(键)-不可变类型

与以连续整数为索引的序列不同,字典以 关键字 为索引,关键字通常是字符串或数字,也可以是其他任意不可变类型。

只包含字符串、数字、元组的元组,也可以用作关键字。

但如果元组直接或间接地包含了可变对象,就不能用作关键字。

列表不能当关键字,因为列表可以用索引、切片、append() 、extend() 等方法修改。

字典的键-唯一

可以把字典理解为 键值对 的集合,但字典的键必须是唯一的。

创建字典

花括号 {} 用于创建空字典。

另一种初始化字典的方式是,在花括号里输入逗号分隔的键值对,这也是字典的输出方式。

dict() 构造函数可以直接用键值对序列创建字典:

>>> dict([('sape', 4139), ('guido', 4127), ('jack', 4098)])
{'sape': 4139, 'guido': 4127, 'jack': 4098}

推导式可以用任意键值表达式创建字典:

>>> {x: x**2 for x in (2, 4, 6)}
{2: 4, 4: 16, 6: 36}

关键字是比较简单的字符串时,直接用关键字参数指定键值对更便捷:

>>> dict(sape=4139, guido=4127, jack=4098)
{'sape': 4139, 'guido': 4127, 'jack': 4098}

字典的主要用途-通过关键字存储、提取值

字典的主要用途是通过关键字存储、提取值。

用 del 可以删除键值对。用已存在的关键字存储值,与该关键字关联的旧值会被取代。通过不存在的键提取值,则会报错。

对字典执行 list(d) 操作,返回该字典中所有键的列表,按插入次序排列(如需排序,请使用 sorted(d))。

检查字典里是否存在某个键,使用关键字 [in]。

以下是一些字典的简单示例:

>>> tel = {'jack': 4098, 'sape': 4139}
>>> tel['guido'] = 4127
>>> tel
{'jack': 4098, 'sape': 4139, 'guido': 4127}
>>> tel['jack']
4098
>>> del tel['sape']
>>> tel['irv'] = 4127
>>> tel
{'jack': 4098, 'guido': 4127, 'irv': 4127}
>>> list(tel)
['jack', 'guido', 'irv']
>>> sorted(tel)
['guido', 'irv', 'jack']
>>> 'guido' in tel
True
>>> 'jack' not in tel
False

数据结构的循环

字典中循环-取出键和值-items()

在字典中循环时,用 items() 方法可同时取出键和对应的值:

>>> knights = {'gallahad': 'the pure', 'robin': 'the brave'}
>>> for k, v in knights.items():
...     print(k, v)
...
gallahad the pure
robin the brave

序列中循环-取出位置和值-enumerate()

在序列中循环时,用 [enumerate()]函数可以同时取出位置索引和对应的值:

>>> for i, v in enumerate(['tic', 'tac', 'toe']):
...     print(i, v)
...
0 tic
1 tac
2 toe

循环多个序列-元素匹配-zip()

同时循环两个或多个序列时,用 [zip()] 函数可以将其内的元素一一匹配

>>> questions = ['name', 'quest', 'favorite color']
>>> answers = ['lancelot', 'the holy grail', 'blue']
>>> for q, a in zip(questions, answers):
...     print('What is your {0}?  It is {1}.'.format(q, a))
...
What is your name?  It is lancelot.
What is your quest?  It is the holy grail.
What is your favorite color?  It is blue.

逆向循环-reversed()

逆向循环序列时,先正向定位序列,然后调用 reversed() 函数:

>>> for i in reversed(range(1, 10, 2)):
...     print(i)
...
9
7
5
3
1

指定顺序循环序列-sorted()

按指定顺序循环序列,可以用 sorted()函数,在不改动原序列的基础上,返回一个重新的序列

>>> basket = ['apple', 'orange', 'apple', 'pear', 'orange', 'banana']
>>> for i in sorted(basket):
...     print(i)
...
apple
apple
banana
orange
orange
pear

循环遍历序列中的唯一元素-set()

使用 set() 去除序列中的重复元素。使用 sorted() 加 set()则按排序后的顺序,循环遍历序列中的唯一元素:

>>> basket = ['apple', 'orange', 'apple', 'pear', 'orange', 'banana']
>>> for f in sorted(set(basket)):
...     print(f)
...
apple
banana
orange
pear

循环中修改列表的内容-创建新列表

一般来说,在循环中修改列表的内容时,创建新列表比较简单,且安全:

>>> import math
>>> raw_data = [56.2, float('NaN'), 51.7, 55.3, 52.5, float('NaN'), 47.8]
>>> filtered_data = []
>>> for value in raw_data:
...     if not math.isnan(value):
...         filtered_data.append(value)
...
>>> filtered_data
[56.2, 51.7, 55.3, 52.5, 47.8]