数据结构中的列表、元组、字典、集合 ,深浅copy

数据结构:数据结构是计算机存储数据和组织数据的方式。数据结构是指相互之间存在一种或多种特定关系的数据元素的集合。在python中主要的数据类型统称为容器。

而序列(如列表、元组)、映射(如字典)、集合(set)就是python中最主要的容器。

序列:成员有序的排列,并且可以通过下标和偏移量访问到他的一个或几个成员的类型统称为序列。他是最基本的数据类型。Python中内建的序列有6种:列表、元组、字符串、Unicode字符串、buffer对象和xrange对象。下面重点介绍列表和元组。

列表

列表:是储存和处理一组有序项目的数据结构。

特点 :

①有序排列

 ②原列表可以改变的。这是它区别于字符串和元组的最重要的特点

③ 异构性.列表中可以存放不同数据类型中的数据

重点:将字符串转换为列表用split,将列表转化为一组字符串用join。

表达式:方括号[ ],每项用逗号(,)隔开。

常用的函数方法:最基本的方法:增删改查。

举例:name =["a","b","c"]

(1)打印列表中的元素c。print(name[2])

(2)打印列表中的元素b,c。print(name[1:3])

(3)打印列表中的最后一个项目。print(name[-1])

(4)打印列表中的最后两个项目。print(name[-2:])

(5)添加有四种方法。

1# name.append("d") ,只能在列表中添加一个元素且只能添加在末尾。

2# name.extend(列表名,元组名等) ,可以添加一个可迭代对象,仅仅是一个,可迭代对象包括元祖,列表,字典,字符串等,多个字符串要放在一个元祖或列表中、且只能添加在末尾。注意最后形成的还是列表。

a = [1, 2, 23, 4]
b = (5, 6, 7, 8, 9)
a.extend(b) #迭代的添加
print(a)

结果:

[1, 2, 23, 4, 5, 6, 7, 8, 9] 

3#name.insert(index,obj), index 想插入的索引号,新的元素将成为该索引号上的元素。obj想要插入的元素。

4#:列表间可以直接相加“+”,但是这种方法不节省内存,因为多开辟了一个内存空间。

举例:

li1=[1,2,3,4]
li2=[5,6,7]
li3=li1+li2

结果:

[1, 2, 3, 4, 5, 6, 7]  迭代着添加

(6)替换。 name[1]="x"

(7)删除。有三种方法:

① del name[index] 可以切片只有它可以切片剩余的都不可以切片. del name 直接删除列表

② name.remove("要删除的元素”)  #如果有多个元素b,默认删除第一个元素b,无返回值  ,没有该元素会报错。

③  name.pop(index)   #函数用于移除列表中的一个元素(如果括号里没有数字则默认删除最后一个元素),并且返回被删除的该元素。如果要显示被删除的元素可以这样写。print(name.pop(index)) 有返回值。

a = [1, 2, 23, 4]
c=a.pop(2) 
print(a)
print(c)

结果:

[1, 2, 4]
23

(8)查找。name.index("要查找的元素")   #结果为要查找的元素的索引号。当存在时返回元素的索引,不存在时报错。列表的方法中没有find(),不要和字符串混淆。

(9)统计。name.count("要查找的元素")   #结果为显示列表里有查找的元素的个数。列表count不能切片,字符串里能切片

(10)清除列表。name.clear()

 (11)反转列表。name.reverse()。反转字母或数字。还可以用切片来反转[::-1]

列表排序

(12)列表永久排序。即在原来的列表中排序列表.

listsort()。只能是数字或字母不能是字母和数字,如果要排要按ASCII,sort(reverse=True)=倒序.

list=[1,5,3,4,2]
list.sort(reverse=True)
print(list)            #排序加反转

结果:

[5, 4, 3, 2, 1]a

 sorted(a)临时排序:它会新建一个列表作为返回值.这个方法可以接受任何可迭代的对象.

a=[2,3,2,6,5]
print('临时排序',sorted(a))
print('a的值',a)

结果:

临时排序 [2, 2, 3, 5, 6]
原来的值 [2, 3, 2, 6, 5]

不管是list.sort还是sorted函数都有两个可选的关键字参数 

reverse

如果被设定为True,被排序的序列里的元素会以降序输出,默认是False即以正序输出

key

key后边跟一个只有一个参数的函数,这个函数会把序列里的每一个元素都放到里边进行计算,排序将使用函数所产生的结果

例子:

>>>a = ["a","ab","abc","abcd"]
>>>sorted(a,key=len) # 按字节长度正序排
['a', 'ab', 'abc', 'abcd']
>>>sorted(a,key=len,reverse=True)  # 按字节长度倒叙排
['abcd', 'abc', 'ab', 'a']

例子2:

b = [{'age': 20, 'name': 'abc'}, {'age': 25, 'name': 'ghi'}, {'age': 30, 'name': 'def'}]


def get_age(s):
    return s["age"]


ff = sorted(b, key=get_age, reverse=True)  # 按年龄值降序排列
print(ff)


# 更优雅的写法
ff = sorted(b, key=lambda x: x["age"], reverse=True)
print(ff)

结果:

[{'age': 30, 'name': 'def'}, {'age': 25, 'name': 'ghi'}, {'age': 20, 'name': 'abc'}]

深浅copy

(13)复制。Python中的复制其实有五种形式。

①一个变量赋值另一变量也是一种复制。

例如:

a = [2, 3]
b = a
print(b)
print(id(a))
print(id(b))


#结果:
[2, 3]
4329912008
4329912008

这种赋值复制,其实就只在内存中开辟了一个空间,并没有新建内存地址,还是用的相同的内存地址。

所以a改变,B就变。注意:这里的改变只是对a进行增删改,并不是对a的重新赋值,如果对于a的重新赋值就是在内存中重新建立空间,重新建立内存地址,这里我们要搞清楚.

,也可以说是引用的传递,只是引用变了,然而值却没有变.

 在这里我们要补充一点知识:

对于python而言,python的一切变量都是对象,变量的存储,采用了引用语义的方式,存储的只是一个变量的值所在的内存地址,而不是这个变量的只本身。

#引用语义
引用语义:在python中,变量保存的是对象(值)的引用,我们称为引用语义。采用这种方式,变量所需的存储空间大小一致,因为变量只是保存了一个引用。也被称为对象语义和指针语义。
#值语义
值语义:有些语言采用的不是这种方式,它们把变量的值直接保存在变量的存储区里,这种方式被我们称为值语义,例如C语言,采用这种存储方式,每一个变量在内存中所占的空间就要根据变量实际的大小而定,无法固定下来。
a=[1,2,4,5,6,7]   #
b=a
a.append(8)

print("a",a,id(a))
print("b",b,id(b))

结果:

a [1, 2, 4, 5, 6, 7, 8] 1518265683848
b [1, 2, 4, 5, 6, 7, 8] 1518265683848

但是有特例注意注意:字符串的原字符串是不可变得,如果要对元字符串的内容改变,是要重新开辟内存地址的。所以这个方法是不适合字符串的。但是对于列表这种可变数据类型来说就可以.

a = [2, 3]
b = a
a = [3]
print(b)
print(id(a))
print(id(b)) 

结果:

[2, 3]
4535325640
4535457480

 ②浅复制(copy)

浅赋值即赋值了最外层的容器

对于浅copy来说,复制第一层时创建了新的内存地址,而从第二层开始都是指向的被复制那层的内存地址。所以对与第二层乃至更深的层次来说,和原列表保持一致。

范例:第一层:

c=[1,2,4,[100,103,105],6,7]
d=c.copy()
c.append(666)

print("c",c,id(c))
print("d",d,id(d))

结果:

c [1, 2, 4, [100, 103, 105], 6, 7, 666] 1487569307720
d [1, 2, 4, [100, 103, 105], 6, 7] 1487569307784

第二层:

a=[1,2,4,[100,103,105],6,7]
b=a.copy()
a[3].append(666)
print("a",a,id(a[3])) #注意是要查看谁的ID地址,而不是查看a的ID
print("b",b,id(b[3]))

结果:

a [1, 2, 4, [100, 103, 105, 666], 6, 7] 1195850256264
b [1, 2, 4, [100, 103, 105, 666], 6, 7] 1195850256264

 ③相当于浅复制的例子。切片同时省略起始索引和中止索引。如b=a[:]。

④深复制(deepcopy)。开辟了新的内存地址.对与深copy,两个是对立的,改变任何一个元素,另一个不会改变。我要复制一个文件,原文件和新文件没有半毛钱的关系.

第一个例子:

 1 mport copy
 2 a=[1,2,3,4,["a","b",["x","z"]]] #原始对象
 3 b=a                #赋值
 4 c=copy.copy(a)     #浅复制
 5 d=copy.deepcopy(a) #深复制
 6 e=a[:]             #另一种复制方式,它不属于copy模块下,也是一种浅复制
 7 a.append("A")     #第一层变动
 8 a[4][2].append("C")#第三层变动
 9 print("a=",a)
10 print("b=",b)
11 print("c=",c)
12 print("d=",d)
13 print("e=",e)
View Code

得到的结果为:

1 a= [1, 2, 3, 4, ['a', 'b', ['x', 'z', 'C']], 'A']
2 b= [1, 2, 3, 4, ['a', 'b', ['x', 'z', 'C']], 'A'] #一点都不忠诚,a变他就变
3 c= [1, 2, 3, 4, ['a', 'b', ['x', 'z', 'C']]]#只忠诚第一层
4 d= [1, 2, 3, 4, ['a', 'b', ['x', 'z']]]#完全忠诚
5 e= [1, 2, 3, 4, ['a', 'b', ['x', 'z', 'C']]]#和c一样只忠诚第一层
View Code

第二个例子:

c=[1,2,4,[100,103,105],6,7]
d=copy.deepcopy(c)
c.append(666)

print("c",c,id(c))
print("d",d,id(d))

结果:

c [1, 2, 4, [100, 103, 105], 6, 7, 666] 2763573379336
d [1, 2, 4, [100, 103, 105], 6, 7] 2763573379272

第三个例子:

import copy
a=[1,2,4,[100,103,105],6,7]
b=copy.deepcopy(a)
a[3].append(666)
print("a",a,id(a))
print("b",b,id(b))

结果:

a [1, 2, 4, [100, 103, 105, 666], 6, 7] 2763573320840
b [1, 2, 4, [100, 103, 105], 6, 7] 

补充一个函数:join() 这个函数不是列表特有的。链接字符串数组,将字符串列表,元组等可迭代对象中的元素以指定的特殊符号字符(分隔符)连接生成一个新的字符串。

结构为:“连接符”.join(可迭代对象)

例子:

li = ["alex","eric","rain"]
temp="_".join(li)
print(temp)

结果为:

alex_eric_rain

列表易错题目:

通过对li列表切片得到新的列表为["c"]

li=[1,3,2,"a","b","c"]
print(li[-1])
print(li[-1:]) 

结果:

c
['c']   #注意对列表切片得到的是列表,对列表取下下标得到的是字符串

数组

Python中还有一种数据结构叫数组(array),它和列表有很大的区别?

计算机为数组分配一段连续的内存,从而支持对数组随机访问;

区别:

  1. 只能存放一种数据类型.在创建数组的时候,就确定了数组的类型

  2.运行效率比列表高

import array
#array模块是python中实现的一种高效的数组存储类型。它和list相似,但是所有的数组成员必须是同一种类型,在创建数组的时候,就确定了数组的类型

#array.array(typecode,[initializer]) --typecode:数据类型代码;initializer:初始化器,若数组为空,则省略初始化器
arr = array.array('i',[0,1,1,3])
print(arr)

#结果
array('i', [0, 1, 2, 3]) 

元组

元组的基本知识

元祖又叫做不可变的列表.

元组用来将多祥的对象集合在一起,它也是序列,和列表类似只不过,元组和字符串一样是不可变的,即你不能修改元组。但是元组还有另外一个和字符串不同的特性儿子不能改,孙子可以改.

元祖的特点:

  1. 元祖中的元素不可以改变.
  2. 有序

作用:对数据的安全记录.

用户希望他的数据不被改变,能够安全的采用一组数据。

语法形式:P=("a","b"," c","d")。用括号括起来,每个元素用逗号隔开。

它的函数方法只有count和index两种,用法和list一样。可以切片,循环。可迭代对象。

 注意:元组的儿子不能替换但是孙子可以替换

题目要求:

  1. 把"xiaoli"替换成"小李” #这个是会报错的,因为元组的儿子不能被替换。
  2. 把“太白”替换成“taibai"
  3. 把“小红”替换成”xiaohong"#这个会报错因为元组的儿子是元组然后它的儿子也不能替换,凡是直系亲属都不可以。
li=(1,"xiaoli",3,4,[1,2,"太白","alex"],("小红","小白"))
li[4][2]="taibai"
print("li2",li)

结果:

li2 (1, 'xiaoli', 3, 4, [1, 2, 'taibai', 'alex'], ('小红', '小白'))

 注意还有一点:当元组内只有一个一个元素时要加逗号(,) 

由圆括号包裹的一个单一元素首
先被作为分组操作,而不是作为元组的分界符。一个变通的方法是在第一个元素后面添一个逗
号(,)来表明这是一个元组而不是在做分组操作。具体什么是分组操作,我也不清楚

a=("",)
b=("")
print(type(a),a)
print(type(b),b)

结果:

<class 'tuple'> ('',)
<class 'str'> 你

元组比较大小时,只比较第一个元素,如果元组1中的第一个元素<元组二中的第一个元素,name元组一<元祖二,当判断等于时,必须所有的元素东等于才会得到True。

print((2, 2) == (2, 2,))
print((3, 2) > (2, 8))
print((1, 5) > (2, 8))

结果:

True
True
False

list()

该方法是做项目遇到的,

该方法有两个作用:

第一个:将集合或元组转换为列表:

b = {"1","2","3"}
print(list(b))
c = ("1","2","3")
print(list(c)
#结果为:['1', '2', '3']

第二个作用:当空列表用

print([]==list())

print(list())

#结果:
TRUE
[]

元组的拆包 

拆包就是把元组中的元素一个个的拆出来,分别赋给不同的变量

如:

name,age = ('小明',13)#要注意元祖中的元素的个数,要和变量一致

print("name",name)
print('age',age)

#拆包结果 
name 小明
age 13

*

* 把一个可迭代对象拆开

people = ('小明',13)

print(*people)

#结果
小明 13

把一个可迭代对象拆开作为函数的参数

count = (14, 7)


def f(a, b):
    return a / b


print(f(*count))

#结果
2.0

*args和**kwargs

*args和**kwargs允许你给函数传不定数量的参数,“不定量”意味着你在定义函数的时候不知道调用者会传递几个参数进来。*args能够接收不定量的非关键字参数,**kwargs能够接收不定量的关键字参数.

args返回的是一个列表.注意是args在这里返回的是一个列表,在函数中返回的是一个元组并不是*args,*args是拆包

a, b, *args = range(5)
print("a", a)
print("b", b)
print("args", args, type(args))  # 注意不要取*args的值,因为*args是拆包
print("*args", *args)

结果:

a 0
b 1
args [2, 3, 4] <class 'list'>
*args 2 3 4

命名元祖namedtuple

详情见https://www.cnblogs.com/sticker0726/articles/11380503.html

 列表元组转换成字典

As = [("A", 1), ("B", 1), ("C", 1)]
bs = [("A", 1), ("F", 2), ("C", 8), ("D", 4)]
a = dict(As)
b = dict(bs)
print(a)
print(b)

结果:

{'A': 1, 'B': 1, 'C': 1}
{'A': 1, 'F': 2, 'C': 8, 'D': 4}

字典 

字典:它是唯一属于映射类型的。字典有键和值组成,键是唯一的键,但是值不是唯一的可以有多个。键必须是可哈希的(不能改变的数据类型:字符串,元组(元组内只包含数组和字母的组合才行),布尔值,数字)。不可哈希:列表,字典,集合。

特点:

1.有序。(在Python3.6之前的版本字典是无序的,但是在3.6版本开始,字典变得有序起来,特别是Python字典有序变为官方的统一规范.) 大神对字典有序的一种解释

2.数据关联性。

3.键唯一性且必须是可哈希的,

4.查找和插入的速度快,不会随着key的增加而变慢。

请务必注意,dict内部存放的顺序和key放入的顺序是没有关系的。

和list比较,dict有以下几个特点:

  1. 查找和插入的速度极快,不会随着key的增加而变慢;
  2. 需要占用大量的内存,内存浪费多。由于字典是使用了散列表来实现的,而散列表又要求必须是稀疏的,稀疏意味着内存中有空白的元素,浪费了大量的空间.

而list相反:

  1. 查找和插入的时间随着元素的增加而增加;
  2. 占用空间小,浪费内存很少。

所以,dict是用空间来换取时间的一种方法。

dict可以用在需要高速查找的很多地方,在Python代码中几乎无处不在,正确使用dict非常重要,需要牢记的第一条就是dict的key必须是不可变对象

这是因为dict根据key来计算value的存储位置,如果每次计算相同的key得出的结果不同,那dict内部就完全混乱了。这个通过key计算位置的算法称为哈希算法(Hash)。

要保证hash的正确性,作为key的对象就不能变。在Python中,字符串、整数等都是不可变的,因此,可以放心地作为key。而list是可变的,就不能作为key

hash算法的时间复杂度是o(1)

 字典常用的方法

:有两种方法。

1.直接修改。如果里边没有,直接添加进字典。如果里边有相同的键会覆盖掉。

ic = {'k1': "v1", "k2": "v2", "k3": [11,22,33]}
dic["k1"]="vv" 
print(dic)

结果:

{'k1': 'vv', 'k2': 'v2', 'k3': [11, 22, 33]}

2.setdefault. 有两个作用

  作用1:如果里边没有,直接添加进字典。如果里边有相同的键,不会添加进字典,保持原来的不变。

dic = {'k1': "v1", "k2": "v2", "k3": [11,22,33]}
dic.setdefault("k3","kk")
print(dic)

结果:

{'k1': 'v1', 'k2': 'v2', 'k3': [11, 22, 33]}

注意看,我们要把kk添加到k3中怎么办?这就用到了setdefault另外一个知识

 作用2:dict.setdefault(key, default=None),当键不存在时,使用默认值

dic = {'k1': "v1", "k2": "v2", "k3": [11,22,33]}
dic.setdefault("k3",[]).append("kk")
print(dic)

#结果:{'k1': 'v1', 'k2': 'v2', 'k3': [11, 22, 33, 'kk']}

  

删:只有3个。

1.pop:按键删除,找到会返回删除内容。找不到会报错。有返回值。

print(dic.pop("key") ) 输出返回值

2.dic.clean():清空字典

3.del dic[key]

dic = {'k1': "v1", "k2": "v2", "k3": [11,22,33]}
del dic["k1"]
print(dic)

结果:

{'k2': 'v2', 'k3': [11, 22, 33]}

有两种:

1.直接赋值。dic[key]=value

2.update()方法用于将dict2的键值对添加到dict。此方法不返回任何内容。有相同键的直接覆盖,没有的直接添加。

dic1 = {'k1': "v1", "k2": "v2", "k3": [11,22,33]}
dic2 = {'k1': "v6", "k8": "v2"} 
dic1.update(dic2)
print(dic1)

结果:

{'k1': 'v6', 'k2': 'v2', 'k3': [11, 22, 33], 'k8': 'v2'}

查:

1.直接查。dic["key"]但是key不存在时会报错,为了解决这个问题,出现了defaultdict,

defaultdict的作用是在于:当字典里的key不存在但被查找时,返回的不是keyError而是一个默认值

defaultdict接受一个工厂函数作为参数,如下来构造:
dict =defaultdict( factory_function)
这个factory_function可以是list、set、str等等,作用是当key不存在时,返回的是工厂函数的默认值,
比如list对应[ ],
str对应的是空字符串,
set对应set( ),
int对应0
from collections import defaultdict

dict4 = defaultdict(list)
print(dict4["hello"])

# 结果
[]

2.dic.get("key"),不存在时返回默认追none,默认值可以自己设置。

3. dic.keys(),会得到一个包含所有key的列表。注意并不是一个真正意义上的列表(因为它不支持切片和索引取值),如果要转化真正的列表只需要这样list(dic.keys()),就可以了

4.dic.values(),会得到一个包含所有value的列表。

5.dic.items(),会的到一个包含所有value和key 的列表,####不建议这么获取字典的值和键,因为这样占内存,应该用以下这种方法来获得。

dic1 = {'k1': "v1", "k2": "v2", "k3": [11,22,33]}
for key in dic1:
    print(key,dic1[key])

结果为:

k1 v1
k2 v2
k3 [11, 22, 33]

  

dic1 = {'k1': "v1", "k2": "v2", "k3": [11,22,33]}
print(dic1.keys())
print(dic1.values())
print(dic1.items())

结果:

dict_keys(['k1', 'k2', 'k3'])
dict_values(['v1', 'v2', [11, 22, 33]])
dict_items([('k1', 'v1'), ('k2', 'v2'), ('k3', [11, 22, 33])])

for 循环的特殊的用法:
dic1 = {'k1': "v1", "k2": "v2", "k3": [11,22,33]} 不建议用这种方法来获取键和值 for key,value in dic1.items(): print(key,value)

结果:

k1 v1
k2 v2
k3 [11, 22, 33]

 如何比较两个字典的大小?

1.字典中的键的个数越多,这个字典就越大。

2.如果键的个数相同,则比较字键在,还没验证

dict()函数

Python 字典 dict() 函数用于创建一个新的字典。

# !/usr/bin/python3
 
dict0 = dict()  # 传一个空字典
print('dict0:', dict0)
 
dict1 = dict({'three': 3, 'four': 4})  # 传一个字典
print('dict1:', dict1)
 
dict2 = dict(five=5, six=6)  # 传关键字
print('dict2:', dict2)
 
dict3 = dict([('seven', 7), ('eight', 8)])  # 传一个包含一个或多个元祖的列表
print('dict3:', dict3)
 
dict5 = dict(zip(['eleven', 'twelve'], [11, 12]))  # 传一个zip()函数
print('dict5:', dict5)

结果:

dict0: {}
dict1: {'four': 4, 'three': 3}
dict2: {'five': 5, 'six': 6}
dict3: {'seven': 7, 'eight': 8}
dict5: {'twelve': 12, 'eleven': 11}

 数据类型的转换:

将
s = [('yellow', 1), ('blue', 2), ('yellow', 3), ('blue', 4), ('red', 1)]

变成
{'yellow': [1, 3], 'blue': [2, 4], 'red': [1]}

比较笨的方法是先定义一个空字典,

s = [('yellow', 1), ('blue', 2), ('yellow', 3), ('blue', 4), ('red', 1)]
d = {}
for k,v in s:
    d.setdefault(k, []).append(v)
print(dict(d))

colliections中给我提供了好的api

 创建字典的几种方法

1.直接创建,冒号隔开
mydict = {‘key’:’value’…}

2.=连接键值对
mydict = dict(key1=value1,key2=value2…)

3. 创建一个空的,慢慢赋值
mydict={}
mydict[key1]=value1
mydict[key2]=value2
4.利用zip压缩两个序列里面的值,组成键值对
keys = [a,b,c,d]
values = [e,f,g,h]
mydict = dict(zip(keys,values))

5.可全部初始化为一个值,然后需要的时候修改
list = ['a','b','c','d']
mydict = dict.fromkeys(list,0)  #可以是任何你想要的值
#结果:
{'a': 0, 'b': 0, 'c': 0, 'd': 0}
————————————————

 dict()方法

在工作中用到了dict()这个方法,在这里记录一下:

#dict()有四种用法
#方式一: dict()生成一个空的字典
#方式二 : dict(**kwargs)
>>>dict(m=5)
{'m': 5}
#方式三:dict(mapping) 生成一个有值的字典
>>>>>dict({"m":3})
{'m': 3}
#方式四:dict(iterable) 生成一个新字典,这里的iterable中的参数必须有两个
>>>dict([("m",2),("n",6)])
{'m': 2, 'n': 6}

场景要求将对象转换成字典

class A(object):
  country = "china"
    def __init__(self):
        self.name = "小红"
        self.age = 12
        self.sex = ""

    def keys(self):
        s = ("country","name", "age", "sex")
        return s

    def __getitem__(self, item):
        print(">>>item", item)
        return getattr(self, item)


a = A()
print(dict(a))  # 执行流程:dict(),首先得到一个空字典,然后调用keys方法拿到所有的键,然后执行a[键],调用__getitem__方法得到每个键对应的值,然后将键值对应放到字典中

结果:

>>>item country
>>>item name
>>>item age
>>>item sex
{'country': 'china', 'name': '小红', 'age': 12, 'sex': ''}

 两个字典中相同键的值相加

from collections import Counter

a = {'A': 1, 'B': 1, 'C': 1}
b = {'A': 1, 'F': 2, 'C': 8, 'D': 4}
X, Y = Counter(a), Counter(b)
z = dict(X + Y)
print(z)

结果:

{'A': 2, 'B': 1, 'C': 9, 'F': 2, 'D': 4}

列表中的字典去重

列表中的字典去重有两种方法

方法一:

fs
c = []
for i in li:
    if i not in c:
        c.append(i)

 方法二:

c = [dict(t) for t in set([tuple(d.items())for d in li])]
print(c)

结果:

[{'d': 1}]

 列表中相同字典key相加

按照type分组计算over_im对应的值

oldList = [{'date': '2019-08-17', 'type': '旅游', 'user_time': 3},
           {'date': '2019-08-17', 'type': '娱乐', 'user_time': 1},
           {'date': '2019-08-17', 'type': '工作', 'user_time': 1},
           {'date': '2019-08-17', 'type': '休闲', 'user_time': 2},
           {'date': '2019-08-17', 'type': '生活', 'user_time': 1},
           {'date': '2019-08-18', 'type': '生活', 'user_time': 8},
           {'date': '2019-08-18', 'type': '旅游', 'user_time': 1},
           {'date': '2019-08-18', 'type': '玩乐', 'user_time': 1},
           {'date': '2019-08-18', 'type': '休闲', 'user_time': 1},
           {'date': '2019-08-18', 'type': '生活', 'user_time': 1},
           {'date': '2019-08-18', 'type': '工作', 'user_time': 1},
           {'date': '2019-08-18', 'type': '游戏', 'user_time': 1},
           {'date': '2019-08-19', 'type': '工作', 'user_time': 5},
           {'date': '2019-08-19', 'type': '游戏', 'user_time': 1},
           {'date': '2019-08-19', 'type': '休闲', 'user_time': 1},
           {'date': '2019-08-19', 'type': '生活', 'user_time': 1},
           {'date': '2019-08-19', 'type': '玩乐', 'user_time': 4}]

计算:

# 先把type对应的值放在一个列表中,不能重复
key_list = []
for i in oldList:
    if i['type'] not in key_list:
        key_list.append(i['type'])
# 根据不同的type初始化我们需要的数据
init = []
for i in key_list:
    init.append({'type': i, 'user_time': 0})

# 相同id的doc_count数相加
for i in oldList:
    for o in init:  # 循环我们初始化的数据,如果发现type相同就立刻break这次循环,防止浪费时间,因为init中的数据不会重复,
        if i['type'] == o['type']:
            o['user_time'] = o['user_time'] + i['user_time']
            break
print(init)

结果:

[{'type': '旅游', 'user_time': 4},
{'type': '娱乐', 'user_time': 1},
{'type': '工作', 'user_time': 7},
{'type': '休闲', 'user_time': 4},
{'type': '生活', 'user_time': 11},
{'type': '玩乐', 'user_time': 5},
{'type': '游戏', 'user_time': 2}]

数据结构转换例题                                                                   

 范例一:

题目要求:

把这种数据格式变量list,转换成变量dict的这种格式

list=[{'url': '/orders/', 'code': 'list', 'pk': 2},
 {'url': '/users/', 'code': 'list', 'pk': 1},
 {'url': '/orders/add/', 'code': 'add', 'pk': 1},
 {'url': '/orders/delete/(\d+)', 'code': 'delete', 'pk': 1},
 {'url': '/orders/edit/(\d+)', 'code': 'edit', 'pk': 1}]
dict = {
    2: {
        "urls": ["/orders/", ],
        "codes": ["list", ]
    },
}

方法:

dict={ } #首先定义一个字典
for i in list:
    if i["pk"] in dict.keys(): #判断变量在不在dict中
        dict[i["pk"]]["urls"].append(i["url"])
        dict[i["pk"]]["codes"].append(i["code"])
    else:
        dict[i["pk"]]={"urls":[i["url"],],
                       "codes":[i["code"]]}

print(dict)

结果:

{2: {'urls': ['/orders/'], 'codes': ['list']}, 
1: {'urls': ['/users/', '/orders/add/', '/orders/delete/(\d+)', '/orders/edit/(\d+)'], 'codes': ['list', 'add', 'delete', 'edit']}}

 集合

 注意集合中的元素不能是列表中含有字典


b = [{"d": 1}]
print(set(b))
#结果 TypeError: unhashable type: 'dict'

列表中可以包含字符串,元组,就是不能有字典和列表

b = [("d",1)]
print(set(b))

# 结果
{('d', 1)}

                                     

原文地址:https://www.cnblogs.com/sticker0726/p/7340601.html