python语法总结2 -数据结构和序列

本文是对python语法中关于数据结构与序列的一个回顾总结,结合《python数据分析》中的相关案例代码记录自己的相关笔记。 

目录

元组

列表   

字典

集合

列表、集合和集合的推导式


元组tuple

元组是一个固定长度,不可改变的Python序列对象。创建元组的最简单方式,是用逗号分隔一列值:
当用复杂的表达式定义元组,最好将值放到圆括号内,如下所示:

tup1=4,5,6 
print(tup1) #注意是元组  
nested_tup=(4,5,6),(7,8)  # 当用复杂的表达式定义元组,最好将值放到圆括号内,注意,此虽然看似是两个元素的赋值,但实际得到的是一个元组!!!  是元素为元组的元组
print(nested_tup)
print(type(nested_tup[0])) # 第一个元素也为元组

# 用tuple可以将任意序列或迭代器转换成元组:  
print(tuple([4,0,2]))  # 注意: 这个直接转换成了元组,而非元素为list的元组   
tup=tuple('string')   # 注意 : 此处将字符串'string'的各个元素的都拆分了成了元素! 得到一个元组!
print(tup) 
print(list('string'))  # list 也同样拆分了

输出:

(4, 5, 6)
((4, 5, 6), (7, 8))
<type 'tuple'>
(4, 0, 2)
('s', 't', 'r', 'i', 'n', 'g')
['s', 't', 'r', 'i', 'n', 'g']

实例2 : # 可以用方括号访问元组中的元素。和C、C++、JAVA等语言一样,序列是从0开始的:
print(tup[0])  输出: s

一旦创建了元组,元组中的对象就不能修改了 ;  但元组中存储的对象可以 是可变对象,如果元组中的某个对象是可变的,比如列表,可以在原位进行修改:

tup = tuple(['foo', [1, 2], True])
# tup[2] = False # 这个会报错,TypeError: 'tuple' object does not support item assignment
tup[1].append(3)
print(tup)

输出: ('foo', [1, 2, 3], True)

可以用加号运算符将元组串联起来如:
(4, None, 'foo') + (6, 0) + ('bar')   输出: (4, None, 'foo', 6, 0, 'bar')

元组乘以一个整数,像列表一样,会将几个元组的复制串联起来: 
('foo', 'bar') * 4

输出: ('foo', 'bar', 'foo', 'bar', 'foo', 'bar', 'foo', 'bar')

元组拆分

# 如果你想将元组赋值给类似元组的变量,Python会试图拆分等号右边的值:
tup=(4,5,6)
a,b,c=tup
print(b)  
#
tup=4,5,(6,7)
a,b,(c,d)=tup  # 注意  即使含有元组的元组也会被拆分:
print(d)
# 使用元组的这个功能 可以快速的替换 变量值  
a,b=1,2
print(a,b)
b,a=a,b # 注意: Python可以这样直接替换实际是,左边形成了一个元组,然后再讲元组的值拆包赋值给两个变量!!! 
print(a,b)

输出: 

5
7
(1, 2)
(2, 1)

因为元组的大小和内容不能修改,它的实例方法都很轻量。其中一个很有用的就是count(也适用于列表),它可以统计某个值得出现频率: 

a=  (1, 2, 2, 2, 3, 4, 2)
print(a.count(2))
#输出  4

元组操作方法:

常见操作的方法tuple是加在前面,与list的.调用略有区别
    删除  del tuple1
    计算长度  len (tup1)
    tuple(list1),将列表list1转换为元组

 

列表 list

与元组对比,列表的长度可变、内容可以被修改。可以用方括号定义,或用list函数:

a_list = [2, 3, 7, None]
tup=('foo','bar','baz')
b_list=list(tup)  #将tuple 类型转换为了 list 
print(b_list)
print(tuple(b_list)) # 将list 类型转换为了 tuple  
# 输出: 
['foo', 'bar', 'baz']
('foo', 'bar', 'baz')

索引
    索引从0开始,用来对单个元素进行访问

切片
    切片:可以对一定范围内的元素进行访问,分片通过冒号相隔的两个索引实现。左闭右开。第三个参数为步长,默认步长为1
    

num=[1,2,3,4,5],使用分片num[1:3],输出2,3。num[1:3:2]输出[2,4]
st=[1,3,4,5,6,8]
print("st[-1]:{}".format(st[-1]))#-1最后一个小标索引
#st[-1]:8
print("st[0:-1]:{}".format(st[0:-1]))#到
#输出st[0:-1]:[1, 3, 4, 5, 6]
print("st[0:-2]:{}".format(st[0:-2]))#输出st[0:-2]:[1, 3, 4, 5]

常见操作

    append,添加对象,list.append(obj),简单的 放到尾部
    extend追加序列 ,用于在列表末尾一次性追加另一个序列中的多个元素值值list.extend(seq)
    count,统计某个元素在列表中出现的次数
    index用于从列表中找出某个值第一个匹配项的索引位置,list.index(obj)
    insert将对象插入到列表list.insert(index,obj)
    pop移除列表第一个项,list.pop()
    remove移除某个值的第一个匹配项
    reverse反向
    sort排序

实例

append 添加元素是整个一股脑儿放到后面,extend 会将对象中的元素拆分再逐个放进去。

# 用append在列表末尾添加元素:
b_list=['foo', 'bar', 'baz']
print(b_list)
print(b_list.append('dwarf'))
#  insert 可以在特定的位置插入元素 
b_list.insert(1,'red') # 与append相比,insert耗费的计算量大,因为对后续元素的引用必须在内部迁移,以便为新元素提供空间,如果是在尾部插入元素,尽量用append 。 
print(b_list)
# append 与extend
c=b_list
b_list.append(['1','2','345']) # 注意 append是整个一股脑儿放到后面
print(b_list)
print(c)
c.extend(['1','2','345'])  #注意:  extend 会将对象中的元素拆分再逐个放进去。
print(c)

输出: 

['foo', 'bar', 'baz']
None
['foo', 'red', 'bar', 'baz', 'dwarf']
['foo', 'red', 'bar', 'baz', 'dwarf', ['1', '2', '345']]
['foo', 'red', 'bar', 'baz', 'dwarf', ['1', '2', '345']]
['foo', 'red', 'bar', 'baz', 'dwarf', ['1', '2', '345'], '1', '2', '345']
******************************

list的深浅拷贝

list的直接拷贝与deep拷贝,注意list的浅拷贝和赋值一样,c 的变化会影响到b_list的 变化。list的深拷贝,两者不再相干,c的变化不会影响b_list的变化  

示例: 

b_list=['foo', 'bar', 'baz']
import copy 
copy_c=copy.copy(b_list) # 注意: list的浅拷贝,和赋值一样,c 的变化会影响到b_list的 变化
print(b_list)
print(c)

print("#####"*13)

### 
b_list=['foo', 'bar', 'baz']
c=copy.deepcopy(b_list) #注意:  list的深拷贝,两者不再相干,c的变化不会影响b_list的变化 
c.append(['1','2','345'])
print(b_list)
print(c)

输出: 

['foo', 'bar', 'baz']
['foo', 'red', 'bar', 'baz', 'dwarf', ['1', '2', '345'], '1', '2', '345']
#################################################################
['foo', 'bar', 'baz']
['foo', 'bar', 'baz', ['1', '2', '345']]

 

 

字典dict

字典可能是Python最为重要的数据结构。它更为常见的名字是哈希映射或关联数组。它是键值对的大小可变集合,键和值都是Python对象。创建字典的方法之一是使用大括号{},用冒号分隔键和值:

empty_dict={}
d1={'a':'some_value','b':[1,2,3,4]}
print(d1)
#输出: {'a': 'some_value', 'b': [1, 2, 3, 4]}
# 你可以像访问列表或元组中的元素一样,访问、插入或设定字典中的元素:
d1[7]='an integer'
print(d1)
print(d1['b'])
# 输出: 
{'a': 'some_value', 'b': [1, 2, 3, 4], 7: 'an integer'}
[1, 2, 3, 4]

用序列创建字典

# 将两个序列配对组合成字典 
mapping={}
for key,value in zip(keys,values):
    mapping[key]=value
print(mapping)
#输出 {'a': 'some_value', 'b': [1, 2, 3, 4], 7: 'an integer'}

# 字典本质上是2元元组的集合,dict 可以接受2元元组的集合

mapping2=dict(zip(keys,values))
print(mapping2)
输出:
{'a': 'some_value', 'b': [1, 2, 3, 4], 7: 'an integer'}

关于字典的默认值,# 注意 get默认会返回None,如果不存在键,pop会抛出一个例外

dict的方法get和pop可以取默认值进行返回  ;  value = some_dict.get(key, default_value) 
等价与  
if key in some_dict:   
   value = some_dict[key]   
else:      
   value = default_value   # 注意 get默认会返回None,如果不存在键,pop会抛出一个例外。
# setdefault用法  字典 setdefault() 函数和 get()方法 类似, 如果键不存在于字典中,将会添加键并将值设为默认值。
dict = {'runoob': 'cainiao', 'google': 'search'} 
print "Value : %s" %  dict.setdefault('runoob', None)
print "Value : %s" %  dict.setdefault('Taobao', 'shangpu') # 不在,则赋值默认值淘宝给taobao了
print dict

####  使用dict 的setdefault方法可以简化代码。 
by_letter = {}  
for word in words:
    letter=word[0]
    by_letter.setdefault(letter,[]).append(word)
print(by_letter)

# 输出
Value : cainiao
Value : shangpu
{'google': 'search', 'Taobao': 'shangpu', 'runoob': 'cainiao'}
{'a': ['apple', 'atom'], 'b': ['bat', 'bar', 'book']}

字典的键: #字典的值可以是任意Python对象,而键通常是不可变的标量类型(整数、浮点型、字符串)或元组(元组中的对象必须是不可变的)。这被称为“可哈希性”。

d={}
d[tuple([1,2,3])]='r'
print(d)
# 输出: {(1, 2, 3): 'r'}

可以用检查列表和元组是否包含某个值的方法,检查字典中是否包含某个键,如 'b' in d1  ,输出 True 

常见操作函数


    dict 函数,直接使用{ },里面为空,构建一个空字典或者,使用dict ,通过键值对序列或其他映射(如字典)来创建字典。创建有多种方式。

student=[('name','小萌'),('number','1001')]
dict3=dict(student)#创建字典
print(dict3)#输出{'name': '小萌', 'number': '1001'}

    len(dict)计算字典中元素的个数,即键的总数
    del dict1[键1],  删除字典1中的与键1对应的键值对
    dict1.clear()  删除字典所有的内容
    dict1.copy()  方法返回一个具有相同键/值对的新字典
    dict1.fromkeys(seq[,value])  ,用于创建一个新字典,以序列seq中的元素做字典的键,value为字典所有键对应的初始值,value未指定时默认为none
    dict1.get(key,default) 返回指定键对应的值,不存在这返回default(未指定default则默认为None)

    dict1.keys(),返回一个包含字典中所有键的元组数组
    dict.values() ,返回dict中所有键对应的值,以列表的形式返回
    dict1.items() ,以列表返回可遍历的(键, 值) 元组列表。

dict = {'Name': 'Runoob', 'Age': 7}
print ("Value : %s" %  dict.items())
out:
Value : dict_items([('Age', 7), ('Name', 'Runoob')])
         wordPairs=sorted(counted_words.items(),key=lambda x:-x[1])#词频降序排序,返回一个词频列表[('c', 4), ('a', 3), ('d', 2), ('b', 1)]
    #counted_words.items()是一个词典,{字1:频数1,字2:频数2},字典 items() 方法以列表返回可遍历的(键, 值) 元组数组。
    #sorted是进行排序的,里面的参数:函数lambda中x[1]为元组第二个数,前加负号代表sorted按降序排序。整体返回按字典中value 降序排序的元组列表

    dict1.update(dict2),用于将dict2中的键/值对添加到dict1中去,如果有相同的键,则覆盖所对应的值
    dict1.pop(key),删除字典给定键 key 所对应的值,返回值为被删除的值。key值必须给出。 否则,返回default值。
    dict1.popitem() 以一个元组序列的形式随机返回并删除字典中的一对键和值(一般删除末尾对),

 

 删除元素,   可以用del关键字(只是删除)或pop方法(pop删除键的同时返回键):

d1[5]='some value'
d1['dummy']='another_value'
print(d1)   
#  删除 
del d1[5]  # 没有任何返回
print(d1)
print("**"*13)
ret=d1.pop('dummy') # 返回删除key对应的value
print(ret)
print(d1)

输出: 

{'a': 'some_value', 'dummy': 'another_value', 'b': [1, 2, 3, 4], 5: 'some value', 7: 'an integer'}
{'a': 'some_value', 'dummy': 'another_value', 'b': [1, 2, 3, 4], 7: 'an integer'}
**************************
another_value
{'a': 'some_value', 'b': [1, 2, 3, 4], 7: 'an integer'}

keys和values是字典的键和值的迭代器方法。虽然键值对没有顺序,这两个方法可以用相同的顺序输出键和值: 

keys=d1.keys()
print(type(keys)) #注意得到的是list的类别
values=d1.values()
print(type(values))
print(keys,values)

# 输出:
<type 'list'>
<type 'list'>
(['a', 'b', 7], ['some_value', [1, 2, 3, 4], 'an integer'])

 

集合

集合是无序的不可重复的元素的集合。你可以把它当做字典,但是只有键没有值。可以用两种方式创建集合:通过set函数或使用大括号set语句,注意和字典一样是大括号{}!

aa=set([2, 2, 2, 1, 3, 3])
print aa 
a = {1, 2, 3, 4, 5}
print(type(a))
# 输出:
#set([1, 2, 3])
#<type 'set'>

集合支持合并、交集、差分和对称差等数学集合运算
 

a = {1, 2, 3, 4, 5}
b = {3, 4, 5, 6, 7, 8}  
#  合并是取两个集合中不重复的元素。可以用union方法,或者|运算符:  
print(a.union(b))
print(a|b)
set([1, 2, 3, 4, 5, 6, 7, 8])
set([1, 2, 3, 4, 5, 6, 7, 8])
# 交集的元素包含在两个集合中。可以用intersection或&运算符: 
print(a.intersection(b))
print(a&b)  # 注意集合的 & 是取交集,并不是取and 
# 输出: 
set([3, 4, 5])
set([3, 4, 5])

常用的集合方法

列表、集合和集合的推导式

列表推导式是Python最受喜爱的特性之一。它允许用户方便的从一个集合过滤元素,形成列表,在传递参数的过程中还可以修改元素。形式如下:

expr for val in collection if condition]
它等同于下面的for循环:
result = []
for val in collection:
    if condition:
    result.append(expr)
    else:
        continue

 

#  列表推导式  
# 给定一个字符串列表,我们可以过滤出长度在2及以下的字符串,并将其转换成大写:   
strings = ['a', 'as', 'bat', 'car', 'dove', 'python']  
[x.upper() for x in strings if len(x)>2]

#输出: ['BAT', 'CAR', 'DOVE', 'PYTHON']

用相似的方法,还可以推导集合和字典。字典的推导式如下所示:  
 dict_cmp={ key-expr: vlaue-expr for value in collection if condition}  

集合、字典 推导式  ,与列表推导式的唯一区别就是 外围的不是方括号而是大花括号 
# set_cmp= { expr for value in collection if condition }  

输出: set([1, 2, 3, 4, 6])

# 注意 还可以用 map 函数进一步简化  
set(map(len,strings))

作为一个字典推导式的例子,我们可以创建一个字符串的查找映射表以确定它在列表中的位置: 注意用了 enumerate 函数

print(strings)
loc_mapping={val: index for index,val in enumerate(strings)}
print(loc_mapping)
# 输出
['a', 'as', 'bat', 'car', 'dove', 'python']
{'a': 0, 'bat': 2, 'python': 5, 'car': 3, 'as': 1, 'dove': 4}

嵌套列表推导式

all_data = [['John', 'Emily', 'Michael', 'Mary', 'Steven'],['Maria', 'Juan', 'Javier', 'Natalia', 'Pilar']]  
names_of_interest=[]
for names in all_data:
    enough_es=[name for name in names if name.count('e')>=2]
    names_of_interest.extend(enough_es)
print(names_of_interest)
# 输出  ['Steven']

## 用嵌套列表推导的方法,可以将这些写在一起  
result=[ name for names in all_data for name in names if name.count('e')>=2]
# 注意 # 嵌套列表推导式看起来有些复杂。列表推导式的for部分是根据嵌套的顺序,过滤条件还是放在最后,但是处理操作放在最前面
print(result)
# 输出  ['Steven']

# 下面是另一个例子,我们将一个整数元组的列表扁平化成了一个整数列表: 注意处理放在最前面
 

some_tuples=[(1,2,3),(4,5,6),(7,8,9)]
flattened=[x for tup in some_tuples for x in tup ]
print(flattened)

输出: 

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

注意: for表达式的顺序是与嵌套for循环的顺序一样(而不是列表推导式的顺序): 
# flattened=[]
# for tup in some_tuples:
#     for x in tup:
#         flattened.append(x)
#  上三级以上的嵌套就需要考虑代码的可读性了

参考与鸣谢:

《python数据分析》

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值