小白 Study Py 数据结构0

数据结构

1.列表list

列表是线性的连续内存空间,是可变的 插入、删除效率低,查找效率高

链表有顺序的,散落存放内存空间 ,上一次元素记录下一个元素一次查找,可以数使用索引 插入、删除效率高,查找效率低,在尾部操作较为合适,分为单、双向链表。

queue:从队首取数据用链表实现的queue,队尾取数据使用列表实现的queue,中间一般不进行操作,分为先进先出和后进先出,以及优先队列。

stack:就是后进先出队列


(1)列表及方法

l1 = []
l2 = list()  空列表
l3 = list(range(5))

l4 = [range(3)] len(l4)= 1
l5 = [list(range(5))]
l6 = list(list(range(5)))#list([1, 2, 3]) ==> [1, 2, 3]
for可迭代的不一定是有序的 eg:箱子里的苹果

列表正索引0-n,负索引-1--- -n,不可以越界

l7 = list(range(10, 15))
[10, 11, 12, 13, 14]
l7.index(10)   #
0
l7.count(11)   #
1

取索引时间复杂度为O(1)(一步到位),index和count时间复杂度为O(n),效率低下,len()时间复杂的为O(1),遍历时间复杂的为O(n)。

append修改原列表,并尾部追加元素,返回值为None,时间复杂度为O(1),不要连续追加,否则会引起垃圾回收或移动(内存)

L.append(n)

insert插入元素,时间复杂度为O(n)

L.insert(index, value)
l.insert(-5000, 6) 头部插入 (可越界)
l.insert(5000, 6) 尾部插入 (可越界)

extend扩展

l.extend(range(1, 100000000))   分配一块内存
l.extend(list(range(1, 10000000)))   分配两大(很多)块内存

列表中引用类型指的是地址

l1 = [[1, 2, 3]] * 3
[[1, 2, 3], [1, 2, 3], [1, 2, 3]]
l1[1] = 100
[[1, 2, 3], 100, [1, 2, 3]]
l1[2][2] = 300
[[1, 2, 300], 100, [1, 2, 300]]

remove(value) -> None 从左到右查找第一个匹配的元素,移除该元素,返回None,时间复杂度O(n)

pop([index]) -> item 从尾部弹出一个元素;指定索引index,从所引处弹出一个元素,索引超标抛出错误。

clear() ->None 对内存处理频繁,垃圾回收慢,清理列表中的元素(不是真的删除,有计数引用)

reverse() -> None 将列表元素反转,就地修改,时间复杂度O(n)

sort(key=None, reverse=False) -> None 对列表元素进行排序,就地修改,默认升序,reverse为True,反转,降序,key=一个函数,按照函数类型排序

列表中in也要遍历,效率不高,少用。

'==' 比较内容


(2)列表复制

shadow copy,影子拷贝,浅拷贝,遇到引用类型,只复制了一个引用

深拷贝,改变引用地址

总结:

  1. 赋值是将一个对象的地址赋值给一个变量,让变量指向该地址,地址不变。
  2. 浅拷贝是在另一块地址中创建一个新的变量或容器,但是容器内的元素的地址均是源对象的元素的地址的拷贝。也就是说新的容器中指向了旧的元素,说明浅拷贝仅仅是复制了容器中元素的地址。
  3. 深拷贝是在另一块地址中创建一个新的变量或容器,同时容器内的元素的地址也是新开辟的,仅仅是值相同而已,是完全的副本。也就是说拷贝了一个副本。

(3)切片

[start : stop : step] 前包后不包,切片操作是浅拷贝copy(),会引起内存复制,相当于又开辟了一块内存空间,一旦长度很大,会引起垃圾回收, 切片赋值是就地修改,内存地址不会变

a = list(range(10))
a[:]
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

a[3:3]
[]

a[3:4]
[3]

a[-1:-3]
[]

a[-3:-1]
[7, 8]

a[4:-5]
[]

a[1:-1:2]
[1, 3, 5, 7]

a[1::2]
[1, 3, 5, 7, 9]

a[:-1:2]
[0, 2, 4, 6, 8]

a[::2]
[0, 2, 4, 6, 8]

a[::-1]
[9, 8, 7, 6, 5, 4, 3, 2, 1, 0]

a[-1:-3:2]
[]

a[-1:-3:-2]
[9]

s = ''.join(map(str, a))
s[:]
s[::]
'9876543210'

b = a[:]
c = a
id(a), id(b), id(c)
(1960368153928, 1960368719816, 1960368153928)
b = [0] + b
id(b)
1960368742216

b[1:2] = (12,)
b
[0, 12, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
b[1:3] = [21, 22, 23, 24]
b
[0, 21, 22, 23, 24, 8, 7, 6, 5, 4, 3, 2, 1, 0]
b[1:5] = ()
b
[0, 8, 7, 6, 5, 4, 3, 2, 1, 0]

c = b[1:3]
b[:] = c
id(b)
1960368742216

2.元组tuple

元组有序不可变,使用()表示

t1 = tuple()
t2 = ()
t3 = (1, )
t4 = (1, 'a', range(4))

t5 = tuple(range(5))
t5[-2]
3

t6 = (1, [2,3], (4, [5]))
t6[2][1][0] = 123
(1, [2, 3], (4, [123]))

t = (1,) * 5
(1, 1, 1, 1, 1)

from collections import namedtuple
Point = namedtuple('Point123', ['x', 'y']) #['a', 'b']
Point
  __main__.Point123
type(Point) #类型
 type
p1 = Point(1, 2)
Point123(x=1, y=2)
p1.x
 1 #a
p1.y
 2 #b

三元表达式

v = value1 if True else value2   #先执行右边,在赋值给左边

3.字符串

(1)format用法

'abc{}'.format(10)
'abc10'
'xyz {} {}'.format('a', 'b')
'xyz a b'
'xyz{0} {0}'.format('a')
'xyza a'
'{} - {}'.format('a', ['b'])
"a - ['b']"

'{0:3}'.format(6) #字符串对象的格式化方法 3--占3个字符宽度
'  6'
'{0:<3}'.format(6)
'6  '
'{0:>3}'.format(6)
'  6'

abs() 内建函数,计算绝对值

print默认使用空格分割,sep='\n'

(2)join()

拼接之后返回新的字符串,括号里面必须为可迭代对象 --> join(iterable)

"".join(list(range(5)))
报错
",".join('abcde')
'a,b,c,d,e'
",".join(str(range(5)))
'r,a,n,g,e,(,0,,, ,5,)'
",".join(map(str, range(5)))
'0,1,2,3,4'
c = ['a', 'b']
':'.join(c)
'a:b'
b = 'a,b,c,d,e'
"".join(b)
'a,b,c,d,e'

(3)+ 字符串拼接

'a' + 'b'
'ab'

d = 'ab' * 5
'ababababab'

字符串可以+=,也可以*=
d += 'c'
d *= 2

(4)split()、patition()

默认使用尽量多的空白字符切割, 立即返回列表(非惰性),range()惰性

a = ",".join(map(str, range(5)))
a.split(',')
['0', '1', '2', '3', '4']

'a b \n \t \r\n c'.split()
['a', 'b', 'c']
'a b \n \t \r\n c'.split(' ')
['a', 'b', '\n', '\t', '\r\n', 'c']

'a  b   c d'.split(' ')
['a', '', 'b', '', '', 'c', 'd']
'a  b   c d'.split('  ')
['a', 'b', ' c d']

'a  b   c d'.split(maxsplit=1)
['a', 'b   c d']

'a  b'.rsplit(' ')  rsplit从右向左切,不影响顺序
['a', '', 'b']

'a  b'.rsplit(' ', maxsplit=1)
['a ', 'b']

'a \t b\nc d\re f\nghi\r\nok'.splitlines()
['a \t b', 'c d', 'e f', 'ghi', 'ok']
'a \t b\nc d\re f\nghi\r\nok'.splitlines(True)    格式符原样输出
['a \t b\n', 'c d\r', 'e f\n', 'ghi\r\n', 'ok']

s2 = '''hello
python'''
s2.splitlines(True)
['hello\n', 'python']

#partition()切出来的是三元组
'a,b'.partition(',')   #,为分割符
('a', ',', 'b')
'a,b,c'.partition(',') #等价于split(' ', 1)
('a', ',', 'b,c')
'a,b,c'.rpartition(',')
('a,b', ',', 'c')
'a,b,c'.rpartition(' ')
('', '', 'a,b,c')
'a,b,c'.partition(' ')
('a,b,c', '', '')

(5)find()、replace()、strip()等

s1 = 'Abc'
s1.upper()
'ABC'
s1.lower()
'abc'
s1.swapcase()
'aBC'
s1.center(20)
'        Abc         '
s1.center(20, '*')
'********Abc*********'

s1.zfill(10)
'0000000Abc'

s1.ljust(10)
'Abc       '

s1.rjust(10)
'       Abc'

s2 = 'www.google.www'
s2.replace('w', 'm')
'mmm.google.mmm'
s2.replace('ww', 'm')
'mw.google.mw'
删空白字符
' I am python \t\r\n '.strip()
'I am python'
' I am python \t\r\n '.ltrip()
'I am python \t\r\n '
' I am python \t\r\n '.rstrip()
' I am python'
strip()从两头删除你指定的空格
' I am python \t\r\n '.strip(' ')
'I am python \t\r\n'
' I am smart smart python as '.strip('I am smart')
'python'

index()返回找到元素所在的索引
s1 = 'I am smart smart python as'
s1.index('s')
5
s1.index('s', 5, 10) = s1.index('s', 5)
5
s1.index('s', 6, 10)
s1.find('s', 6, 10) >=0 说明一定在字符串中, 返回值大于等于0,找到,反之没找到
-1
if s1.find('s', 6, 10) >=0:
    pass
s1.find('o', -6, -1)
21
's' in sq
True
#startswith()和endswith()时间复杂度为O(1)
s1.startswith('am', 2)
True
s1.endswith('am', 2, 12)
False
s1.endswith('am', -100, 100)
True

s1 = 'I am smart smart python as'
len([s1])
1

s3 = 'abc123
s2.isalpha() #字母
False
s2.isdight() #数字
False
s2.sidecima() #十进制
False
''.isspace()  #空白字符
True
'abc231_'.isidentifier() #是否为标识符

(6)字符串格式化

"%d %s" % (a, b) d为数字 s为字符串," ".format() " ".format(*)

"%d %s" % (1, 2)
'1 2'
"%d %03d" % (1, 2)
'1 002'
"%03d" % (1,)
'001'
"%03d%%" % 1  %%转义
'001%'
"0x%X" % 10
'0xA'

"{0[0]}.{0[1]}.{0[2]}".format(('www', 'nice', 'python'))
'www.nice.python'
"{}*{}={}".format(2, 3, 6)
'2*3=6'
"{}*{}={:02}".format(2, 3, 6)
'2*3=06'
"{:$^20}".format('26')
'$$$$$$$$$26$$$$$$$$$'
"{:^20}".format('26')
'         26         '
"{0:#x} {0:#b} {0:#0}".format(127)
'192 168 0 1'
"{:#02X} {:02X} {:#03X} {:02X}".format(*[192, 168, 0, 1])
'0XC0 A8 0X0 01'

print("{:f}".format(1))
1.000000
print("{:20.2f}".format(321))
              321.00
print("{:.3}".format(123.1111))
1.23e+02
print("{:.3%}".format(123.1111))
12311.110%

(7)编码

编码(encode())是编成二进制数据,解码(decode())是将二进制转成字符,默认使用utf-8

#记一下
0xD----->\r
0xA----->\n
0x9----->\t
0x31--->1
0x41--->A
0x61--->a

(8)bytes、bytearray、int

(1)bytes和bytearray

1)bytes定义:

  • bytes() 空bytes

  • byres(int) 指定字节的bytes,被0填充

  • bytes(iterable_of_ints) -> bytes[0-255]的int组成的可迭代对象

  • bytes(string, encoding[, errors]) 等价于bytes.encoding()

  • bytes(bytes_or_buffer) ->从一个字节序列或者buffer复制出一个行的不可变的bytes对象

  • 使用b前缀定义:只允许基本ASCII使用字符形式b'abc'

  • 使用16进制表示b'\x41\x61'

2)bytes操作

和str类型类似,都是不可变类型,输入输出都是bytes

b'abcdef'.replace(b'f', b'k')
result:b'abcdek'
b'abc'.find(b'b')
result:1

类方法bytes.fromhex(string),string必须是2个字符的16进制的形式

bytes.fromhex('6162 09 6a 6b00')
result:b'ab\tjk\x00'

hex() 返回16进制表示的字符串

'abc'.encode().hex()
result:'616263'

索引 b'abcdef'[2]返回该字节对应的数,int类型

b'abcdef'[2]
result:99

3)bytearray定义

  • bytearray() 空bytearray
  • bytearray() 指定字节的bytearray,被0填充
  • bytearray(iterable_of_ints) -> bytearray[0-255]的int组成的可迭代对象
  • bytearray(string, encoding[, errors]) 近似bytearray.encoding(),返回可变对象
  • bytearray(bytes_or_buffer) ->从一个字节序列或者buffer复制出一个行的不可变的bytes对象

4)bytearray操作

和bytes类型方法相同

bytearray(b'abcdef').replace(b'f', b'k')
result:bytearray(b'abcdek')
bytearray(b'abc').find(b'b')
result:1

类方法bytearray.fromhex(string),string必须是2个字符的16进制的形式

bytearray.fromhex('6162 09 6a 6b00')
bytearray(b'ab\tjk\x00')

hex() 返回16进制表示的字符串

bytearray('abc'.encode()).hex()
result:'616263'

索引 b'abcdef'[2]返回该字节对应的数,int类型

bytearray(b'abcdef')[2]
result:99

bytearray其他操作:

  • append(int) 尾部追加一个元素
  • insert(index, int) 在指定索引位置插入元素
  • extend(iterable_of_ints) 将一个可迭代的整数集合追加到当前的byterray
  • pop(index=-1) 从指定索引上移除元素,默认从尾部移除
  • remove(value) 找到第一个value删除,找不到ValueError抛异常
  • clear() 清空 bytearray
  • reverse() 翻转bytearray,就地修改

(2)int和bytes

1)int.from_bytes(bytes, byteorder) 将一个字节数组表示成整数

2)int.to_bytes(leng, byteorder) byteorder是字节序列,将一个整数表达成一个指定长度的字节数组

i = int.from_bytes(b'abc', 'big')
print(i, hex(i))
print(i.to_bytes(3, 'big'))
result:
6382179 0x616263
b'abc'

bytes是不可变类型,bytearray是可变类型

(9)解构(拆箱)

t1 = 1, 2
t2 = (1, 2)
t1 == t2  ==> True
id(t1), id(t2)
(1937158003144, 1937158035720)

a, b = 1, 2
a, b = b, a  原理是先将右边的封装成tuple,在解构(拆箱)分配给左边,并不是直接的交换,交换只是视觉效果,解构左右和个数都要一致。否则报错
a, b = [1, 2]

(1, 2)
a, b = {1, 3}
(1, 3)

a, b = {'x':100, 'y':101}
('x', 'y')

a, b = '12'
('1', '2')
a, b = list('12')
('1', '2')
a, b = tuple('12')
('1', '2')
t=tuple(12,) ---------------->报错,里面不是可迭代对象

a, b = bytes(2)        #byte后面2个0
(0, 0)

[a, b] = 100, 101
(a, b) = 100, 101
(100, 101)
{a, b} = 100, 101  # 报错集合无序,拆箱后无法分配

a, *b = 1, 2, 3, 4
(1, [2, 3, 4])
*a, b = 1, 2, 3, 4
([1, 2, 3], 4)
a, *b, c = 1, 2, 3, 4
(1, [2, 3], 4)
a, *b, c, d= 1, 2, 3, 4
(1, [2], 3, 4)
a, *b = (1) # 报错
a, *b = (1,)
(1, [])
*b = 1, 2, 3, 4   # 报错,左边标识符不可*开头,赋值即定义
(*b,) = 1, 2, 3, 4
[1, 2, 3, 4]
a, *b, *c, d = list(range(10)) # 报错,语法错误,中间不知道给谁分配
a, *b, c = 'abcdefg'
('a', ['b', 'c', 'd', 'e', 'f'], 'g')

(10)丢弃变量

_是一个合法标识符,是不想不使用的变量,丢弃的变量

_, *_, a = 1, 2, 3, 4
print(_)
print(a)
print(_)
[2, 3]
4
[2, 3]

#使用解构把4输出
lst = [1, (2, 3, 4), 5]
a, b, c = lst
*v1, v2 = b
v2

lst = [1, (2, 3, 4), 5]
a, (*v1, v2), c = lst
v2

#使用解构把java_home和/usr/bin输出
a, b = 'java_home=/usr/bin'.split('=', maxsplit=1)
a, b

a, _, b = 'java_home=/usr/bin'.partition('=')
a, b
# _

#使用解构
lst = [1, 9, 8, 5, 6, 7, 4, 3, 2]
length = len(lst)
for i in range(length - 1):
    for j in range(length - 1 - i):
        if lst[j] > lst[j+1]:
#             t = lst[j]
#             lst[j]= lst[j+1]
#             lst[j+1] = t

            lst[j], lst[j+1] = lst[j+1], lst[j]
print(lst)

4.集set

set 可变的、无序的、不重复的元素的集合,还有可变的是list和bytearray。

s1 = set()
set = {1, 2, 3}
s2 = set(range(6))
s2 = set(list(range(6))  多此一举
s3 = {1, 'a', range(3)}
s7 = {1, 'a', tuple(range(3))}
{(0, 1, 2), 1, 'a'}

哈希和set()

哈希本质上就是连续的空间,里面要装元素,散列放置,元素内容无序,取模就是哈希运算。 list是不可哈希的,set也是不可哈希的,set元素必须可以哈希,不能使用索引,因为它是无序的,set可以迭代。

add(elem) 增加一个元素,如果元素在什么都不做

update(*others) 合并其他元素到set集合中来,others必须是可迭代对象,就地修改

remove(elem) 从set中移除元素,元素不在,抛出keyerror异常

discard(elem) 移除一个元素,元素不存在什么都不做

pop() --> 移除一个元素,时间复杂度都为O(1),因为都是通过哈希( y=hash(x))直接定位到元素位置clear() 移除所有元素

线性结构和非线性结构: set占空间较大,用哈希计算直接定位,使用in操作效率较高,而list可以保存重复数据,in操作从头到尾遍历,效率较低。

可hash: 数值型int、float、complex,布尔型True、False,字符串string、bytes,None,set的元素必须是可hash的 unionunion

4.集合

(1)定义

全集:所有元素的集合

并集:多个集合并的结果,union(*others),返回多个集合合并后的集合,符号 '|',update(*others) , 符号 '|='

交集:多个集合的公共部分, intersection_update(*others),获取和多个集合的交集,就地修改,符号 '&='

差集:集合中除去和其他集合公共的部分, diffrence(*others),返回和多个集合的差集,符号 '-',difrence_update(*others) ,符号'-='

对称差集:集合A和B,由所有不属于A和B的交集元素组合的集合,sysmmetric_diffrence(other),返回和另一个集合的差集,符号 '^',sysmmtric_difference_update(other),符号 '^='

(2)集合的运算

issubset(other) ==> 符号''<='',判断当前集合是否是另一个集合的子集

set1 < set2 判断set1是否为set2的真子集

issuperset(other) ==> 符号">=",判断但钱集合是否是other的超集

set1 > set2 判断set1是否为set2的超集

isdisjoint(other),当前集合和另一个集合有没有交集,就没有交集返回True

#计算随机生成数重复个数和不重复的个数
import random
a = []
b = []
c = set()
for _ in range(10):
    a.append(random.randint(10, 20))
    b.append(random.randint(10, 20))
n1 = set(a)
n2 = set(b)
print(n1, n2)
print(len(n1 | n2))

n3 = n1 & n2
print(n3, len(n3))
n4 = n1 ^ n2
print(n4, len(n4))
#nice
x = 4
x += x > 3 and 12
x

5.dict

(1)定义

字典是可变的无序的不可重复的

d1 = dict() #空字典
d2 = {}
d3 = {'a':1}
d4 = {'a':1, 1:1, 2:None, 3:'abc', 4:[], (5,):4}
d5 = {1:1, 2:None, 3:'abc', 1:'dict'}
d6 = dict(a=1, b=2, c='abc')
{'a': 1, 'b': 2, 'c': 'abc'}
d7 = dict(d6, d=100, e=231)
{'a': 1, 'b': 2, 'c': 'abc', 'd': 100, 'e': 231}
d8 = {'a':0, 'a':{}, 'c':None, 'd':set(), 'e':[], 'f':(), 'g':'', 'h':b''}
{'a': 0, 'b': {}, 'c': None, 'd': set(), 'e': [], 'f': (), 'g': '', 'h': b''}
d8 = dict(([1, 'a'], [2, 'b']))
{1: 'a', 2: 'b'}

d = dict(([a, '100'], [3, '200']))    报错,nameerror

(2)方法

dict.fromekeys(iterable, value)

d1 = dict.fromkeys(range(4))
d1
{0: None, 1: None, 2: None, 3: None}
d2 = dict.fromkeys(range(4), 'c')
d2
{0: 'c', 1: 'c', 2: 'c', 3: 'c'}

d[key] 字典赋值,将key对应的值修改为value,key不存在添加新的kv对

get(key,[default]) 字典中如果没有,给一个缺省值,不抛出异常,如果有,返回key对应的value

d = dict(([2, '100'], [3, '200']))
d.get(2, 300)
100
d.get('a', None)
None
d['a']        ---------- keyerror

setdefault(key, default),返回key对应的值,如果key不存在,设置新的键值对,没有设置返回value

d = dict(([2, '100'], [3, '200']))
d.setdefault(1, ['a', 1])
d
{2: '100', 3: '200', 1: None}

update([other])--->None,使用另一个字典的kv对来更新字典,key不存在,就添加,存在就覆盖原来的值,就地修改

d = dict(([2, '100'], [3, '200']))
d.update(r=123)
{2: '100', 3: '200', 1: None, 'r': 123}
d.update((('a', 121),))
d.update(a=121)
{2: '100', 3: '200', 'a': 121}
d.update({'b':898})
{2: '100', 3: '200', 'a': 121, 'b': 898}
d.update({2:898})
{2: 898, 3: '200', 'a': 121, 'b': 898}

pop(key, default) key存在,移除它,并返回它的value,key不存在,返回default,default未设置抛异常

popitem() 移除任意一个键值对,若字典为空抛出异常,随机去拿,返回二元组

clear() 清空字典

del语句,删除字典内容

(3)字典的遍历

for k in d:             #遍历key
    print(d[k])
for k in d.keys():
    print(k)
for v in d.values():
    print(v)
for k in d:
    print(d.get(k))
for item in d.items():
    print(item)
for k,v in d.items():
    print(k,v)
for item in d.items():
    print(item)
for k,v in d.items():
    print(k,v)
for k,_ in d.items():
    print(k)
for _,v in d.items():
    print(v)

1 in d.value():
    pass
1 in d:
    pass             # in遍历key效率较高,遍历value相当于遍历列表,效率低

keys返回一个类似于set的对象,可以看作一个set的集合

d.keys() | {1, 2, 3}
d.values() | {1, 2, 3}  #报错,因为values可变,不可哈希,set中不能放不可哈希的元素
set(d.values()) | {1, 2, 3}

遍历value时,不可以删除value,字典遍历时不可以删除,列表可以,但要反向删除
keys = list('abcde')
for i in range(len(keys)):
    keys.pop()
for i in range(len(keys)):
     keys.pop(i)
print(keys)
  • 字典遍历总结:

keys、values、items方法返回一个类似生成器的可迭代对象,不会把函数返回结果复制到内存中,Dictionnary view对象,可以用len()、iter()、in操作;字典的entry的动态视图,字典变化,试图将反应这些变化;keys返回一个set集合,如果values可以哈希,items也可以看作是类set对象。字典的key要求和set的元素一致,必须可哈希。

(4)defauldict

collection.default[default_factory[.....]],第一参数是deafault_factory,缺省是None,它提供一个初始化函数。当key并不存在的时候,会调用这个工厂函数生成key对应的value

from collections import default
import random

d = default(list)  #set dict
for k in 'abcdef':
    for i in range(random.randint(1, 5)):
        d[k].append(i)
print(d)

import random
from collections import defaultdict
d = defaultdict(set)
for k in 'abcd':
    for v in range(random.randint(1, 5)):
        d[k].add(random.randint(1, 100))
print(d)
defaultdict(<class 'set'>, {'a': {56, 82, 32}, 'b': {33, 28}, 'c': {4, 7}, 'd': {16, 50, 83, 86}})

import random

d1 = {}
for k in 'abcd':
    for v in range(random.randint(1, 5)):
        if k not in d1.keys():
            d1[k] = []
        d1[k].append(random.randint(1, 100))
print(d1)

(5)OrderedDict

key并不是按照加入的顺序排列,可以使用OrderedDict记录顺序

from collections import OrderedDict
import random
d = {'apple':2, 'pig':4, 'cat':1}
print(d)
keys = list(d.keys())
random.shuffle(keys)
print(keys)
od = OrderedDict()
for key in keys:
    od[key] = d[key]
print(od)
print(od.keys())

python3.6记录字典顺序只是插入顺序,并不是有序。python3.5可以看出无序

6.解析式

(1)列表解析式

语法:[返回值 for 元素 in 可迭代对象 if 条件],返回一个新的列表,不会减少效率,反而因优化提高了效率

[i for i in range(20) if i % 2 == 0 or i % 3 == 0] 
[0, 2, 3, 4, 6, 8, 9, 10, 12, 14, 15, 16, 18]
[i for i in range(20) if i % 2 == 0 and i % 3 == 0]
[0, 6, 12, 18]
[i for i in range(20) if i % 2 == 0 if i % 3 == 0]
[0, 6, 12, 18]

[[x, y] for x in 'ab' for y in range(2)]
[['a', 0], ['a', 1], ['b', 0], ['b', 1]]
[(x, y) for x in 'ab' for y in range(2)]
[('a', 0), ('a', 1), ('b', 0), ('b', 1)]
[{x, y} for x in 'ab' for y in range(2)]
[{0, 'a'}, {1, 'a'}, {0, 'b'}, {1, 'b'}]

lst = [print(i) for i in range(6)]  #lst为5个None,print返回为None

(2)生成器表达式

语法:(返回值 for 元素 in 可迭代对象 if 条件),列表解析式的中括号换成小括号,返回一个生成器,生成器是可迭代对象,迭代器。

和列表解析式区别:生成器表达式按需计算(惰性求值),需要的时候才计算,从头计算到尾,不回头,列表解析式是立即返回值,返回可迭代对象列表,从头到尾计算一遍,可以回头迭代,从内存的角度来说,生成器所占内存极少,只有使用返回数据,而列表要立即占用内存,生成器只返回生成对象,列表要返回新的列表,所以计算速度生成器更快。

it = (x for x in range(10) if x % 2)
first = next(it)
1
second = next(it)
3
val = first + second
4

(3)集合解析式

语法:{返回值 for 元素 in 可迭代对象 if 条件},立即返回一个集合

{{x, x+1} for x in range(10)}
{[x] for x in range(10)}  #不可以,[x]不可哈希

(4)字典解析式

语法:{返回值 for 元素 in 可迭代对象 if 条件},使用key:value形式,立即返回一个字典

{x:(x, x+1) for x in range(10)}
{x:[x, x+1] for x in range(10)} 

转载于:https://my.oschina.net/u/3844908/blog/3003741

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值