python中的数据结构及其常见用法

数据结构

list(列表)



# list.append(x)
squares = [1, 2, 3, 4 ,5, 6]
squares.append(10)
print(squares) # [1, 2, 3, 4, 5, 6, 10]

# list.extend(iterable)
iterable = [x * 2 for x in squares]
squares.extend(iterable)
print(squares)  # [1, 2, 3, 4, 5, 6, 10, 2, 4, 6, 8, 10, 12, 20]

# list.insert(i, x)
square2 = [1, 2, 3, 4]
square2.insert(2, 11)
print(square2) # [1, 2, 11, 3, 4]

# list.remove(x)
square3 = [1, 2, 3, 4]
square3.remove(2)
print(square3) # [1, 3, 4]

# list.pop([i])
square4 = [1, 2, 3, 4]
square4.pop(2)
print(square4) # [1, 2, 4]
square4.pop()
print(square4) # [1, 2]

# list.clear()
square5 = [1, 2, 3, 4]
square5.clear()
print(square5) # []

# list.count
square5 = [1, 2, 3, 4]
square5.clear()
print(square5) # []

# list.sort(key=None, reverse=false)
square6 = [1, 2, 3, 3, 4]
print(square6.count(3)) # 2

# list.clear()
square5 = [1, 2, 3, 4]
square5.clear()
print(square5) # []

# list.copy() => 返回浅拷贝
square6 = [1, 2, 3, 4]
square7 = square6.copy()
print(square7) # [1, 2, 3, 4]
square7.remove(2)
print(square7) # [1, 3, 4]
print(square6) # [1, 2, 3, 4]

# list.reverse()
square8 = [1, 2, 3, 4]
square8.reverse()
print(square8) # [4, 3, 2, 1]

# list.index(x[, start[, end])
square9 = [1, 2, 3, 4]
print(square9.index(2)) # 2的索引值为1
print(square9.index(2, 0, 9)) # 1

你可能会注意到的另一件事是,并非所有数据都可以排序或比较。例如,[None,‘hello’,10]之所以不能排序,是因为不能将整数与字符串进行比较,而不能将None与其他类型进行比较。另外,有些类型没有定义排序关系。例如,3 + 4j < 5 + 7j不是有效的比较。
也可以将列表用作队列,其中添加的第一个元素是检索到的第一个元素(“先进先出”);但是,列表对于此目的并不有效。尽管从列表末尾开始的添加和弹出很快速,但是从列表开头进行插入或弹出是很慢的(因为所有其他元素都必须移位一个)。


from collections import deque
queue = deque(["Eric", "John", "Michael"])
queue.append("Terry")           # deque(['Eric', 'John', 'Michael', 'Terry'])
print(queue)

queue.append("Graham")          # deque(['Eric', 'John', 'Michael', 'Terry', 'Graham'])
print(queue)

queue.popleft()                 # deque(['John', 'Michael', 'Terry', 'Graham'])
print(queue)

queue.popleft()                 # deque(['Michael', 'Terry', 'Graham'])
print(queue)

列表推导

列表推导可以很精简的创建一个列表

# 传统方法
ary = []
for var in range(10):
       ary.append(var)
print(ary) # [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

# 列表推导方式
ary2 = [x for x in range(0, 10)]
print(ary2) # [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

ary3 = [1, 2, 3, 4, 5]
new_ary3 = list(map(lambda x: x ** 2, ary3))
print(new_ary3) #  [1, 4, 9, 16, 25]

# 等价于上面一种写法
ary4 = ary3.copy()
new_ar4 = [x**2 for x in ary4]
print(new_ar4) #  [1, 4, 9, 16, 25]

列表推导由包含表达式的方括号组成,后跟一个for子句,然后是零个或多个for或if子句。结果将是一个新列表,该列表是通过在紧随其后的for和if子句的上下文中计算表达式而得出的:

ary1 = [1, 2, 3, 4, 5, 6]
ary2 = [1, 2, 3, 4, 5, 6]
combine_ary = [(x, y) for x in ary1 for y in ary2 if x != y]
print(combine_ary)

# 等价于上面
arr = []
for x in ary1:
        for y in ary2:
                if x == y: continue
                arr.append((x, y))
print(arr)

vec = [-4, -2, 0, 2, 4]
print([x * 2 for x in vec])      # [-8, -4, 0, 4, 8]
print([x for x in vec if x > 0]) # [2, 4]
print([abs(x) for x in vec])     # [4, 2, 0, 2, 4]


# 调用方法处理元素,返回一个新的数组
freshfruit = ['  banana', '  loganberry ', 'passion fruit  ']
print([x.strip() for x in freshfruit]) # ['banana', 'loganberry', 'passion fruit']

# print([x, x**2 for x in range(6)]) # error
vec = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
print([num for elem in vec for num in elem])

# 等价于上面
new_ary2 = []
for x in vec:
        for y in x:
            new_ary2.append(y)
print(new_ary2)

from math import pi
print([str(round(pi, i)) for i in range(1, 6)])

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

print([[ary[i] for ary in matrix] for i in range(0, len(matrix))]) #  [[1, 5, 9], [2, 6, 10], [3, 7, 11]]

# same as above
new_ary3 = []
for i in range(len(matrix)):
        new_ary3.append([ary[i] for ary in matrix])
print(new_ary3) # [[1, 5, 9], [2, 6, 10], [3, 7, 11]]

# same as above
new_ary4 = []
for i in range(len(matrix)):
        temp_ar = []
        for ary in matrix:
                temp_ar.append(ary[i])
        new_ary4.append(temp_ar)
print(new_ary4) # [[1, 5, 9], [2, 6, 10], [3, 7, 11]]

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

delete 语句

a = [-1, 1, 66.25, 333, 333, 1234.5]
del a[0]
print(a) # [1, 66.25, 333, 333, 1234.5]

del a[2:4]
print(a) # [1, 66.25, 1234.5]

del a[:] # same as a.clear()
print(a) # []

元组和序列

元组由逗号分隔开的元素组成,元组是不可变得。

t = 12345, 54321, 'hello!'
print(t[0]) # 12345

# Tuples may be nested:
u = t, (1, 2, 3, 4, 5)
print(u) #  ((12345, 54321, 'hello!'), (1, 2, 3, 4, 5))

# Tuples are immutable:
t[0] = 88888 # error


# but they can contain mutable objects:
v = ([1, 2, 3], [3, 2, 1])
print(v) # ([1, 2, 3], [3, 2, 1])

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

print(len(singleton)) # 1

print(singleton) # ('hello', )

x, y, z = t # unpack tuple

这被适当地称为序列解压缩,适用于右侧的任何序列。序列解压缩要求等号左侧的变量与序列中的元素一样多。注意,多重分配实际上只是元组打包和序列拆包的组合。

集合

Python还包括集合的数据类型。集合是没有重复元素的无序集合。基本用途包括成员资格测试和消除重复条目。集合对象还支持数学运算,例如并集,交集,差和对称差。
花括号或set()函数可用于创建集合。注意:要创建一个空集,必须使用set(),而不要使用{};后者会创建一个空字典。

aa = {1, 2, 3}
bb = {1, 2, 3, 4, 5, 6}
print(aa - bb)

print(aa | bb) # {1, 2, 3, 4, 5, 6}
print(aa & bb) # {1, 2, 3}
print(aa ^ bb) # {4, 5, 6}
print(set('abcdefg')) #  {'b', 'd', 'g', 'a', 'e', 'f', 'c'}
print({'apple', 'apple', 'orange'}) # {'apple', 'orange'}

集合也支持列表推导

a = {x for x in 'abracadabra' if x not in 'abc'}
print(a) # {'r', 'd'}
print(set('abc') ^ set('abracadabra')) # same as {'r', 'd'}

字典

tel = {'jack': 4098, 'sape': 4139}
tel['guido'] = 4127
print(tel) # {'jack': 4098, 'sape': 4139, 'guido': 4127}
print(tel['jack']) # 4098

del tel['sape']
tel['irv'] = 4127
print(tel) # {'jack': 4098, 'guido': 4127, 'irv': 4127}

print(list(tel)) # ['jack', 'guido', 'irv']
print(sorted(tel)) # ['guido', 'irv', 'jack']
print('guido' in tel) # True
print('jack' not in tel) # False

dict()构造函数直接从键值对序列中构建字典:

print(dict([[1, 2], [2, 3]])) # {1: 2, 2: 3}
print(dict([(1, 2), (2, 3)])) # {1: 2, 2: 3}

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

#如果键是字符串,则可以用关键字参数形式来创建一个字典
print(dict(sape=4139, guido=4127, jack=4098))  # {'sape': 4139, 'guido': 4127, 'jack': 4098}

循环

当遍历字典时,可以使用items()方法同时检索键和对应的值。

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

遍历序列时,可以使用enumerate()函数同时检索位置索引和相应的值。


for i, v in enumerate(['tic', 'tac', 'toe']):
    print(i, v)

要同时循环两个或多个序列,可以将这些条目与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))

要反向循环一个序列,请先在正向指定序列,然后调用reversed()函数。

for i in reversed(range(1, 10, 2)):
    print(i)

要按排序顺序循环显示序列,请使用sorted()函数,该函数返回一个新的排序列表,同时保持源不变。


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

当遍历列表时,有时很想更改列表。但是,创建新列表通常更简单,更安全。


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)

print(filtered_data) # [56.2, 51.7, 55.3, 52.5, 47.8]

条件判断的更多情况

while和if语句中使用的条件可以包含任何运算符,而不仅仅是比较。
in和not in比较运算符检查序列中是否出现值(不发生)。运算符比较两个对象是否确实是同一对象;是否比较?这仅适用于可变对象(如列表)。所有比较运算符都具有相同的优先级,该优先级低于所有数值运算符的优先级。
比较可以是链式的。例如, a < b == c 测试a是否小于b并且b等于c.

布尔运算符和和或所谓的短路运算符:它们的自变量从左到右进行求值,并且在确定结果后立即停止求值。例如,如果A和C为true但B为false,则A和B与C不会对表达式C求值。当用作通用值而不是布尔值时,短路运算符的返回值是最后一个表达式计算值。

string1, string2, string3 = '', 'Trondheim', 'Hammer Dance'
non_null = string1 or string2 or string3
print(non_null) # 'Trondheim'

var = 0 or 2
print(var) # 2

var2 = 1 and 3
print(var2)  # 3

比较序列和其他类型

通常可以将序列对象与具有相同序列类型的其他对象进行比较

print((1, 2, 3)              < (1, 2, 4))               # True
print([1, 2, 3]              < [1, 2, 4])               # True
print('ABC' < 'C' < 'Pascal' < 'Python')                # True
print((1, 2, 3, 4)           < (1, 2, 4))               # True
print((1, 2)                 < (1, 2, -1))              # True
print((1, 2, 3)             == (1.0, 2.0, 3.0))         # True
print((1, 2, ('aa', 'ab'))   < (1, 2, ('abc', 'a'), 4)) # True
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值