Python之列表和元组

01 序列

成员有序排列的,且可以通过下标偏移量访问到它的一个或者几个成员,这类类型统称为序列

  •  序列数据类型包括:字符串,列表,和元组类型
  •  特点: 都支持下面的特性
  •  索引与切片操作符
  •  成员关系操作符(in , not in)
  •  连接操作符(+) & 重复操作符(*)

02 列表

01 列表的创建

数组: 存储同一种数据类型的集合。

列表: 可以存储任意数据类型的集合。

  1. 创建一个空列表:list=[]
# 创建一个空列表
li = []
print(li, type(li))
 
#测试:
[] <class 'list'>

      2.创建一个包含元素的列表,元素可以是任意类型

包括数值类型,列表,字符串等均可, 也可以嵌套列表如 list =["fentiao", 4, 'gender']

# 列表(打了激素的数组): 可以存储任意数据类型的集和。
li = [1, 1.2, 2e+10, True, 2+3j, 'hello', [1, 2, 3]]
print(li, type(li))
 
#测试:
[1, 1.2, 20000000000.0, True, (2+3j), 'hello', [1, 2, 3]] <class 'list'>

注:li[10:]将输出 [] ,并且不会导致一个 IndexError 。

一个讨厌的小问题是它会导致出现 Bug ,并且这个问题 是难以追踪的,因为它在运行时不会引发错误。

li = [[2,3,4],'a','b','c','d','e',[1,2,3]]
print(li[10:])
print(li[1:])
print(li[:3])
print(li[0][1])
 
#结果为:
[]
['a', 'b', 'c', 'd', 'e', [1, 2, 3]]
[[2, 3, 4], 'a', 'b']
3
 
#值得注意的是列表li里面并没有第10个元素,但结果没有报错,而是输出了[],这就会容易导致bug。

02.列表的特性:index(索引), slice(切片), in/not in, 连接(+), 重复(*)(与字符串类似)

# 列表的特性: index, slice, in/not in, 连接, 重复
li = [1, 1.2, 2e+10, True, 2+3j, 'hello', [1, 2, 3]]
print(li[2])    # 2e+10
print(li[-1])   # [1, 2, 3]
print(li[1:4])  # [1.2, 2e+10, True]   #[m,n],输出的是第m到n-1的元素。
print(li[:4])   # [1, 1.2, 2e+10, True], 获取列表的前4个元素,[:m]输出的是第前m-1个元素。
print(li[2:])   # [2e+10, True, 2+3j, 'hello', [1, 2, 3]], 获取除了前2个元素之外的其他元素。
print(li[:])    # 列表的拷贝
print(li[::-1]) # 列表的反转
 
# 嵌套索引
print(li[-1])  # [1, 2, 3]
print(li[-1][0])    # 1
 
print(1 in li)      # True
print(1 not in li)  # False
 
print([1, 2, 3] + [3, 4, 5])    # [1, 2, 3, 3, 4, 5]
print([1]*10)                   # [1, 1, 1, 1, 1, 1, 1, 1, 1, 1]
 
#结果:
20000000000.0
[1, 2, 3]
[1.2, 20000000000.0, True]
[1, 1.2, 20000000000.0, True]
[20000000000.0, True, (2+3j), 'hello', [1, 2, 3]]
[1, 1.2, 20000000000.0, True, (2+3j), 'hello', [1, 2, 3]]
[[1, 2, 3], 'hello', (2+3j), True, 20000000000.0, 1.2, 1]
[1, 2, 3]
1
True
False
[1, 2, 3, 3, 4, 5]
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1]

03.列表的其他特性:字符串是不可变的数据类型, 列表是可变的数据类

# 字符串是不可变的数据类型, 列表是可变的数据类型
 
li = [1, 2, 3, 4]
print("更改之前的id:", id(li))
li[0] = 100
print("更改之后的id:", id(li))
print(li)
 
结果:
更改之前的id: 1530869313736
更改之后的id: 1530869313736
[100, 2, 3, 4]

4.列表的增、删、改、查

1)增:(append)追加、(insert)插入、(extend)扩展

  • 列表可通过append追加一个元素到列表中;
  • 列表可通过extend方法拉伸, 实现追加多个元素到列表中;
  • 在指定位置添加元素使用insert方法; L.insert(index, object)

如:

li = [1, 2, 3, 4]
li.append(7)
print(li)
 
li.insert(0, 'python')
print(li)
 
li.extend([6, 7, 8, 9])
print(li)
 
#结果:
[1, 2, 3, 4, 7]            #末尾追加元素7
['python', 1, 2, 3, 4, 7]     #在第0个元素处插入元素python
['python', 1, 2, 3, 4, 7, 6, 7, 8, 9]    #在列表扩展几个元素

2)删:(remove)、(del)、(clear)清空、(pop)弹出 

  • list.remove()删除列表中的指定元素。
  • list.pop()根据元素的索引值进行删除指定元素。
  • list.clear: 清空列表里面的所有元素。

如:

li = ['python', 1, 2, 3, 4, 7, 6, 7, 8, 9]
li.remove(1)
print(li)
 
delete_item = li.pop()            #默认弹出最后一位
print(delete_item, li)
 
del li[0]
del li[:2]
print(li)
 
 
li.clear()
print(li)
 
#结果为:
['python', 2, 3, 4, 7, 6, 7, 8, 9]
9 ['python', 2, 3, 4, 7, 6, 7, 8]
[4, 7, 6, 7, 8]
[]

3)改(索引)、(切片)

  • 修改列表的元素:直接重新赋值;
li = ['python', 1, 2, 3, 4, 7, 6, 7, 8, 9]
li[0] = 'python language'
print(li)
 
li[:2] = [1, 2]     #把列表li的前两位替换为1,2
print(li)
 
#结果为:
['python language', 1, 2, 3, 4, 7, 6, 7, 8, 9]
[1, 2, 2, 3, 4, 7, 6, 7, 8, 9]

4)查(count)、(index)

  • 查看某个列表元素的下表用index方法;
  • 查看某个列表元素出现的次数用count方法;

如:

li = ['python', 1, 2, 3, 4, 7, 6, 7, 8, 9]
print(li.index(1))
print(li.count(1))
 
 
结果为:
1                  #元素1第一次出现在第1个元素的位置
1                   #元素1在列表中出现的次数为1次

5)其他操作(copy)复制、(sort)排序(默认从小到大)、(reverse)(反转)、(random)(随机)

如:

li = ['python', 1, 2, 3, 4, 7, 6, 7, 8, 9]
import random
li = list(range(10))
random.shuffle(li)
print(li)
 
li1 = li.copy()
print(li, li1)
 
li.reverse()
print(li)
 
li.sort()
print(li)
 
#结果为:
[7, 0, 3, 4, 2, 1, 5, 6, 9, 8]
[7, 0, 3, 4, 2, 1, 5, 6, 9, 8] [7, 0, 3, 4, 2, 1, 5, 6, 9, 8]
[8, 9, 6, 5, 1, 2, 4, 3, 0, 7]
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

总结如下:

03 元组 

01 元组定义

元组也是一种序列。元组使用圆括弧“0”来界定;元组中各元素之间用逗号隔开。元组不支持修改或删除其所包含的元素。如果要修改,则可以使用list函数把它转化成列表,然后在列表上进行修改创建元组的方法有三种

  1. 使用圆括弧“0”来创建,例如,a=(1,2,3);
  2. 使用逗号来创建,例如,b=2,4;
  3. 使用 tuple0函数把其他种类的序列转化为元组,例如,c= tuple(“Good!”)。

元组是一种序列,它支持序列的基本操作,包括索引、切片、序列加、序列乘、in、len()、max()、min()。元组不可修改,指的是元组中每个元素的指向永远不变。例如,元组a=('Tim',201607,['Python',71]),其中a[1]=201607是整型数据,元组a不能修改a[1];a[2]=['Python',71]是列表,元组a可以修改a[2][1]。元组a的第二个元素为列表,列表的内容是允许改变的,它的内存位置并没有变化。
 

tuple_test=(1,2,"sdsd",[3,4])
print(id(tuple_test))
tuple_test[3][1]=100
# tuple_test[2]='ssss'  不可修改 发生错误
# tuple_test[0]=2       不可修改 发生错误
print(tuple_test)
print(id(tuple_test))

运行结果:

02 元组的创建,删除及特性

1). 定义空元组                    tuple =()
2). 定义单个值的元组         tuple =(fentiao,)
3). 一般的元组                    tuple =(fentiao, 8, male)
注意:元组和列表类似, 可以存储任意数据类型的数据。 列表是可变数据类型(是否有增删改的内置方法), 元组是不可变数据类型.

#  元组的定义
tuple = (1, 2, 3, 4)
print(tuple, type(tuple))
 
# 定义空元组
none_tuple = ()
print(none_tuple, type(none_tuple))
 
 
#定义只有一个元素的元组
one_item_tuple = (1, )      #注意:这个,千万不能忘记了
print(one_item_tuple, type(one_item_tuple))
 
# 元组和列表类似, 可以存储任意数据类型的数据。 列表是可变数据类型(是否有增删改的内置方法), 元组是不可变数据类型.
many_items_tuple = (1, 2.897, 34e-9, True, [1, 2, 3, 4], (1, 2, 3, 4))
print(many_items_tuple, type(many_items_tuple))
 
 
# 元组的特性
t = (1, 2, 3, 4, 5, 6)
# 索引和切片
print(t[0])  # 1
print(t[-1])    # 6
print(t[:2])    # (1, 2)
print(t[:-1])   # (1, 2, 3, 4, 5)
print(t[2:])    # (3, 4, 5, 6)
 
# 成员操作符
print(1 in t)
print(1 not in t)
 
# 重复和连接
print((1, 2, 3) + (1, ))
print((1, 2) * 3)
 
#结果:
(1, 2, 3, 4) <class 'tuple'>
() <class 'tuple'>
(1,) <class 'tuple'>
(1, 2.897, 3.4e-08, True, [1, 2, 3, 4], (1, 2, 3, 4)) <class 'tuple'>
1
6
(1, 2)
(1, 2, 3, 4, 5)
(3, 4, 5, 6)
True
False
(1, 2, 3, 1)
(1, 2, 1, 2, 1, 2)

03 元组的内置方法 index count

t.count(value)-->int              返回value在元组中出现的次数;

t.index(value)                      返回value在元组中的偏移量(即索引值)

t = [1, 2, 3, 1, 2, 3]
print(t.index(1))
print(t.count(1))
 
#结果为:
0
2

04 元组赋值应用:有多少个元素,就用多少个变量接收

特性1: 对元组分别赋值,引申对多个变量也可通过元组方式分别赋值。

name, age, gender = 'fentiao', 10, 'male'
print(name, age, gender)
fentiao 10 male

特性2:x, y, z=1, 2,'westos'等价于 (x, y, z)=(1, 2,'westos') , 等号两边的对象都是元组并且元组的小括号是可选的

# 小范例: 去掉最高分和最低分, 求平均得分
scores = [98, 67, 78, 99, 100]
scores.sort()
# *scores在python3中可以使用, 在python2中不可以使用。
low_score, *other_scores, high_score = scores
print("最低分: ", low_score)
print("最高分: ", high_score)
print("平均分列表: ", other_scores)
print("平均分:%.2f "%(sum(other_scores) / len(other_scores)))
 
#结果为:
最低分:  67
最高分:  100
平均分列表:  [78, 98, 99]
平均分:91.67 

特性3:变量交换

x=2; y=10;x, y =y, 2; print(x,y)

这种交换方式无需中间变量即可交换两个变量的值。

x = 2;y = 3
x,y = y,x
print(x,y)
 
结果:
3 2

 

特性4: print打印

print("name: %s, age:%d, gender: %s" %('fentiao', 10, 'male'))
t = ('fentiao', 10, 'male')
print("name: %s, age:%d, gender: %s" %(t[0], t[1], t[2]))
print("name: %s, age:%d, gender: %s" %t)
 
#结果为:
name: fentiao, age:10, gender: male
name: fentiao, age:10, gender: male
name: fentiao, age:10, gender: male

04 is和==的区别

问题: is和==两种运算符在应用上的本质区别是什么?
1). Python中对象的三个基本要素,分别是:id(身份标识)、type(数据类型)和value(值)。
2). is和==都是对对象进行比较判断作用的,但对对象比较判断的内容并不相同。
3). ==用来比较判断两个对象的value(值)是否相等;(type和value)
    is也被叫做同一性运算符, 会判断id是否相同;(id, type 和value)
 

>>> li = [1,2,3]
>>> li1 =li.copy()
>>> li2 = li[:]
>>> id(li),id(li1),id(li2)
(11840208, 11839408, 11839768)
>>> li,li1
([1, 2, 3], [1, 2, 3])
>>> li == li1
True
>>> li is li1
False                #li和li1的id不相同,所以False
>>> 

 05 深拷贝和浅拷贝

1.问题: 深拷贝和浅拷贝的区别?
问题: 深拷贝和浅拷贝的区别?/python中如何拷贝一个对象?
 
赋值: 创建了对象的一个新的引用,修改其中任意一个变量都会影响到另一个。(=)
 
浅拷贝: 对另外一个变量的内存地址的拷贝,这两个变量指向同一个内存地址的变量值。(li.copy(), copy.copy())
              •公用一个值;
              •这两个变量的内存地址一样;
              •对其中一个变量的值改变,另外一个变量的值也会改变;
 
深拷贝: 一个变量对另外一个变量的值拷贝。(copy.deepcopy())
              •两个变量的内存地址不同;
              •两个变量各有自己的值,且互不影响;
              •对其任意一个变量的值的改变不会影响另外一个;

#浅拷贝
>>> li = [1,2,3]
>>> li1 = li
>>> li,li1
([1, 2, 3], [1, 2, 3])
>>> li.append(4)
>>> li,li1
([1, 2, 3, 4], [1, 2, 3, 4])
>>> li3 = li.copy()
>>> id(li),id(li3)
(56684872, 48078160)
>>> li.append(5)
>>> li,li3
([1, 2, 3, 4, 5], [1, 2, 3, 4])
>>> li4 = li.copy()
>>> li4
[1, 2, 3, 4, 5]
>>> id(li),id(li4)
(56684872, 8050488)

#深拷贝
>>> from copy import deepcopy
>>> li = [[1,2],[1,2,3]]
>>> li2 = deepcopy(li)
>>> id(li),id(li2)
(63828336, 55331576)
>>> id(li[0]),id(li2[0])
(55332056, 55374952)
>>> 

练习:

1.最后一个单词的长度:(字符串)

题目描述:给定一个仅包含大小写字母和空格 ' ' 的字符串,返回其最后一个单词的长度。
如果不存在最后一个单词,请返回 0 。
说明:一个单词是指由字母组成,但不包含任何空格的字符串。
示例:   输入: "Hello World"
           输出: 5

思路:1.首先排除不是单词的输入;

           2.其次让输入的字符串先用切片分隔开;

           3. 反转字符串,从反转后的字符串的第一个元素开始遍历,遇到第一个空格结束,并输出长度

string = input("请输入包含大小写字母和空格的字符串:")              #例如输入‘hello world’
if string == ' ' or not string:              #如果输入为空或者只有空格,输出0
    print(0)
else:
    item_string = string.split(' ')          #用切片经字符串以空格分开
#print(item_string)                          #输出是['hello', 'world']
    print (len(item_string[::-1][0]))      #先将列表反转['python', 'hello'],再遍历第一个元素的长度

2.删除字符串中重复的字母:(字符串)

牛牛有一个由小写字母组成的字符串s,在s中可能会有依稀字母重复出现;
但牛牛不喜欢重复,对于同一个字母,她只想保留第一次出现并删除掉后面出现的字母;
输入一个字符串s,s的长度 1 <= length <= 1000,s中的每个字符都是小写英文字母,请帮牛牛完成对s的操作 。
示例:输入:banana

           输出:ban

思路:1.输入一个字符串s,再定义一个空字符串items用来装不重复的字符串

           2.s的长度 1 <= length <= 1000,s中的每个字符都是小写英文字母,设置变量i如果不在items,则把变量i放入items

           3.输出items
 

s = input("请输入字符串:")
items = " "                              #定义一个空字符串
if 1 <= len(s) <= 1000 and s.islower():  #字符串s的长度大于等于1小于等于100,且必须为小写
    for i in s:
        if i not in items:
            items += i
print(items)

3.[吉比特校招编程题]桌面数字混合排序

描述:

 字符串的 for 循环

 字符串的常用判别函数: isdigit()、isalpha()

分支流程控制

 自学内容: sorted 内置方法实现排序

number=input('请输入字符串:')#输入数字
b=[]#定义b
c=[]#定义c
for i in number:#遍历其中所有数据
    if i.isdigit():
        b.append(int(i))#在数字尾部加上元素
    elif i.isalpha():
        c.append(str(i))#在字母尾部加上元素
b.sort()#将数字从小到大排列
c.sort()#将字母从a-z排列
d=[]
d=c+b#合并数字、字母两个列表
e = [str(j) for j in d]
f=''.join(e)#将列表中的元素拼接到一起
print(f)

4.两数之和(列表,前提是己经排好序的列表)
描述:

给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那 两个 整数,并返回他们的数组下标。
你可以假设每种输入只会对应一个答案。但是,你不能重复利用这个数组中同样的元素。
示例:

给定 nums = [2, 7, 11, 15], target = 9

因为 nums[0] + nums[1] = 2 + 7 = 9,所以返回 [0, 1]

思路:

1.用一个嵌套循环把nums列表遍历两次

代码:

 
class Solution:
    def twoSum(self,nums, target):
        """
        :type nums: List[int]
        :type target: int
        :rtype: List[int]
        """
        #用len()方法取得nums列表的长度
        n = len(nums)
        #x取值从0一直到n(不包括n)
        for x in range(n):
            #y取值从x+1一直到n(不包括n)
            #用x+1是减少不必要的循环,y的取值肯定是比x大
            for y in range(x+1,n):
                #假如 target-nums[x]的某个值存在于nums中
                if nums[y] == target - nums[x]:
                    #返回x和y
                    return x,y
                    break
                else:
                    continue

5.删除数组重复项(列表)

描述:给定一个排序数组,你需要在原地删除重复出现的元素,使得每个元素只出现一次,返回移除后数组的新长度。

不要使用额外的数组空间,你必须在原地修改输入数组并在使用 O(1) 额外空间的条件下完成。

示例 1:

给定数组 nums = [1,1,2], 

函数应该返回新的长度 2, 并且原数组 nums 的前两个元素被修改为 1, 2。 

你不需要考虑数组中超出新长度后面的元素。
示例 2:

给定 nums = [0,0,1,1,1,2,2,3,3,4],

函数应该返回新的长度 5, 并且原数组 nums 的前五个元素被修改为 0, 1, 2, 3, 4。

你不需要考虑数组中超出新长度后面的元素。
 

class Solution(object):
    def removeDuplicates(self, nums):
        """
        :type nums: List[int]
        :rtype: int
        """
        length=len(nums)
        count=0
        for i in range(1,length):
            if nums[count]!=nums[i]:
                nums[count+1]=nums[i]
                count+=1
        return count+1

6.旋转数组:
描述:给定一个数组,将数组中的元素向右移动 k 个位置,其中 k 是非负数。

示例 1:

输入: [1,2,3,4,5,6,7] 和 k = 3
输出: [5,6,7,1,2,3,4]
解释:
向右旋转 1 步: [7,1,2,3,4,5,6]
向右旋转 2 步: [6,7,1,2,3,4,5]
向右旋转 3 步: [5,6,7,1,2,3,4]

全部翻转:7 6 5 4 3 2 1  前k旋转:5 6 7 4 3 2 1 后k旋转:5 6 7 1 2 3 4 
示例 2:

输入: [-1,-100,3,99] 和 k = 2
输出: [3,99,-1,-100]
解释: 
向右旋转 1 步: [99,-1,-100,3]
向右旋转 2 步: [3,99,-1,-100]
说明:尽可能想出更多的解决方案,至少有三种不同的方法可以解决这个问题。
要求使用空间复杂度为 O(1) 的 原地 算法。

思路:

1.三个翻转 , 整体翻转, 前k翻转,后k翻转

class Solution:
    def rotate(self, nums: List[int], k: int) -> None:
        """
        Do not return anything, modify nums in-place instead.
        """
        n = len(nums)
        k %= n
        nums[:] = nums[::-1]
        nums[:k] = nums[:k][::-1]
        #print(nums)
        nums[k:] = nums[k:][::-1]
        print(nums)

参考自https://blog.csdn.net/daidadeguaiguai/article/details/103393717

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

chde2Wang

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值