【Python】语法基础---7、序列结构

1.7 序列结构

可变对象和与可变对象

Python中内置数据类型主要有三大类:

  • 数字:整型、浮点型

  • 序列:字符串、列表、元组、集合

  • 映射:字典

按照是否可以原地修改分为两大类:

  • 不可变对象(数字,字符串,元组,不可变集合)

    不可变的分类中没有哪个对象类型支持原地修改,但可以创建新的对象并将结果赋予变量

  • 可变对象(列表,字典,可变集合)

    相反,可变的类型总是可以通过相关的操作进行原处修改,而不需要创建新的数据对象

序列的通用操作

索引,切片,相加,相乘,迭代和成员资格检查

索引操作

索引中的所有元素都有编号(角标),角标从0开始计数,当然在Python当中,也可以使用负角标来访问元素,所有最后一个元素的角标-1(倒数第一个)

>>> word = "hello"
>>> word[0]
'h'
>>> word[2]
'l'
>>> word[-1]
'o'
>>> word[-5]
'h'
>>> word[10]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
IndexError: string index out of range

对于序列的字面量,可以直接用角标操作,而不需要变量

>>> "hello"[3]
'l'
>>> "hello"[-1]
'o'

切片操作

索引是一次去一个数据,切片是一次取一片数据,要定开始和结尾,包括步长(默认为1)

>>> word = "12345678"
>>> word[0:3]
'123'
>>> word[-3:-1]
'67'

不管是正索引,还是负索引,必须要保证顺序

>>> word[1:8:2]
'2468'
>>> word[-6:-2:3]
'36'
>>> word[7:1:-2]
'864'
>>> word[-1:-5:-1]
'8765'
>>> word[-1:-5:1]
''
>>> word[:]
'12345678'
>>> word[2:]
'345678'
>>> word[:5]
'12345'
>>> word[-5:]
'45678'
>>> word[-3::-1]
'654321'

步长是正数,开始~结尾 递增

步长是负数,开始~结尾 递减

>>> text = "我爱你"
>>> text = text[::-1]
>>> text
'你爱我'
>>> text = text[-1:-4:-1]
>>> text
'我爱你'

相加操作

指的是两个序列合并,会产生新的序列对象,不会改变原先序列的值

>>> s1 = "abc"
>>> s2 = "ABC"
>>> s1 + s2
'abcABC'
>>> s1
'abc'
>>> s2
'ABC'

相加只能是在同类型序列之间进行

相乘操作

将序列与数字x相乘,将重复这个序列x次创建一个新的序列

>>> s1
'abc'
>>> s3 = s1 * 3
>>> s3
'abcabcabc'

迭代操作

可以在for循环中迭代序列中的每一元素,或者迭代角标来获取元素

>>> s1
'abc'
>>> for i in s1:
...     print(i)
...
a
b
c
>>> for i in range(len(s1)):
...     print(s1[i])
...
a
b
c
​
>>> word[0] = '9'
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'str' object does not support item assignment

成员资格检查操作

就是验证一个数据元素是否存在于当前序列当中

>>> '8' in word
True
>>> 8 in word
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'in <string>' requires string as left operand, not int
​
>>> '10' not in word
True
>>> '10' in word
False
>>> 5 in range(0,10)

字符串

不可变对象,一个有序的字符集合,用于存储和表现基本文本信息

字符串不允许原地修改值,字符串的长度大小一旦定义则不能修改

如果真想去修改字符串的话,只能创建一个该字符串的副本,副本的内容就是修改过后的内容

测试字符串方法:

  • isalnum():验证是否只包含数字和字母

  • isalpha():验证是否只包含字母

  • isdigit():验证是否只包含数字

  • isidentifier():验证是否是合法的标识符

  • islower():验证内容当中字母是否全小写

  • isupper():验证内容当中字母是否全大写

  • isspace():验证是否只包含空格

搜索字符串方法:

  • endswith(str):验证是否已str后缀结尾

  • startswith(str):验证是否已str前缀开始

  • find(str):返回str从左到右第一次出现的角标,如果不存在返回-1。rfind()相反

  • index(str):功能和find一样,如果不存在则有异常

  • count(str):记录str出现的次数,不带覆盖

转换字符串:

  • capitalize():将字符串复制并大写第一个字母

  • lower():将所有字母转小写

  • upper():将所有字母转大写

  • title():将字符串复制并将每个单词的首字母大写

  • swapcase():将字符串复制,将小写转大写,将大写转小写

  • replace(a,b):将原先字符串中a替换为b,产生新字符串

  • split(str):将str为分隔符,将字符串分割,结果是一个字符列表

  • partition(str):以str为中心部分,将字符串分为左右两部分

删除字符串空格:

  • lstrip():删除字符串左边的空格

  • rstrip()

  • strip()

格式化字符串:

  • center(w):以w为宽度,让内容居中显示

  • ljust()

  • rjust()

>>> "123abc".isalnum()
True
>>> "我爱你123abc*!&@%#^&%&".isalnum()
False
>>> "abc".isalpha()
True
>>> "123".isalpha()
False
>>> "123abc".isalpha()
False
>>> "123".isdigit()
True
>>> "abc".isdigit()
False
>>> "sum".isidentifier()
True
>>> "123abc".isidentifier()
False
>>> "abc".islower()
True
>>> "ABC".islower()
False
>>> "123abc".islowe()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'str' object has no attribute 'islowe'
>>> "123abc".islower()
True
>>> "     ".isspace()
True
>>> " ad asd asd".isspace()
False
>>> "123,456,789".find("456")
4
>>> "123,456,789".rfind("456")
4
>>> word = "123456789456"
>>> word.find("456")
3
>>> word.rfind("456")
9
>>> word
'123456789456'
>>> word.index("123")
0
>>> word.index("456")
3
>>> word.find("666")
-1
>>> word.index("666")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: substring not found
>>> "121212121".count("121")
2
>>> name = "anglababy"
>>> name.capitalize()
'Anglababy'
>>> name
'anglababy'
>>> "Andy Mimi Lala".lower()
'andy mimi lala'
>>> "Andy Mimi Lala".lower().upper()
'ANDY MIMI LALA'
>>> "mynameishaha".title()
'Mynameishaha'
>>> "my name is haha".title()
'My Name Is Haha'
>>> s= "my name is haha".title()
>>> s
'My Name Is Haha'
>>> s.swpacase()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'str' object has no attribute 'swpacase'
>>> s.swapcase()
'mY nAME iS hAHA'
>>> s = "宇智波萨斯尅,宇智波马达啦,宇智波一大气,宇智波欧鼻头"
>>> s.replace("宇智波","千手")
'千手萨斯尅,千手马达啦,千手一大气,千手欧鼻头'
>>> s
'宇智波萨斯尅,宇智波马达啦,宇智波一大气,宇智波欧鼻头'
>>> s.split(",")
['宇智波萨斯尅', '宇智波马达啦', '宇智波一大气', '宇智波欧鼻头']
>>> l = s.split(",")
>>> l[1]
'宇智波马达啦'
>>> "莫西莫西海雅库摩多摩多".partition("雅")
('莫西莫西海', '雅', '库摩多摩多')
>>> "123456789".partition("456")
('123', '456', '789')
>>> "    123".lstrip()
'123'
>>> "123   ".rsrtip()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'str' object has no attribute 'rsrtip'
>>> "123   ".rstrip()
'123'
>>> "    8798    ".strip()
'8798'
>>> "I Love You".center(16)
'   I Love You   '
>>> s = "abc"
>>> s.center(10)
'   abc    '
>>> s.ljust(10)
'abc       '
>>> s.rjust(10)
'       abc'

列表

列表是Python中最具有灵活性的有序集合对象类型,与字符串不同的是,列表可以包含任何种类的对象:数字、字符串、甚至是列表。同样,与字符串不同的是,列表是可变对象,他们都支持在原处修改的操作,同样列表的长度是可变的。

可变:列表空间中,所存储并指向某个数据对象的地址是可变的

列表的创建方式

直接指定元素

>>> [1,2,3,4,5]
>>> l = [1,2,3,4,5]

指定长度但不指定元素,相当于创建一个长度为n但不存任何数据对象地址的空列表

>>> l = [None] * 10
>>> l
[None, None, None, None, None, None, None, None, None, None]

通过list函数将其他的数据转换为列表,这些数据必须是可迭代的,可迭代的就是可以被for循环操作

>>> list() # 得到一个长度为0的列表
[]
>>> l = list("abcd")
>>> l
['a', 'b', 'c', 'd']
>>> l[0]
'a'
>>> l[-1]
'd'
>>> l = list(range(0,5))
>>> l
[0, 1, 2, 3, 4]
>>> l  =list(1234)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'int' object is not iterable

列表的特有操作

  • 修改元素

    >>> l
    [0, 1, 2, 3, 4]
    >>> l[0]=5
    >>> l
    [5, 1, 2, 3, 4]
  • 切片修改

    >>> l = [1,2,3,4,5,6,7,8,9]
    >>> l
    [1, 2, 3, 4, 5, 6, 7, 8, 9]
    >>> l[3:7] = [666,888,999]
    >>> l
    [1, 2, 3, 666, 888, 999, 8, 9]
  • 删除操作

    >>> l
    [1, 2, 3, 666, 888, 999, 8, 9]
    >>> del l[3]
    >>> l
    [1, 2, 3, 888, 999, 8, 9]
    >>> del l[-3]
    >>> l
    [1, 2, 3, 888, 8, 9]
    >>> del l   # 删除列表对象 连着变量也一同删除
    >>> l
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    NameError: name 'l' is not defined

列表的内置函数

  • append():在列表的表尾添加一个元素对象

    >>> l = [1,2,3]
    >>> l.append(4)
    >>> l
    [1, 2, 3, 4]
    >>> l1 = [1,2,3,4]
    >>> l2 = [5,6,7,8]
    >>> l1.append(l2)
    >>> l1
    [1, 2, 3, 4, [5, 6, 7, 8]]
    >>> l1.append("abc")
    >>> l1
    [1, 2, 3, 4, [5, 6, 7, 8], 'abc']
  • clear():清空列表,不代表删除列表对象

    >>> l.clear()
    >>> l
    []
  • copy():复制一份新的列表对象,与原列表内容一致,将新列表的地址返回

    >>> l1 = [1,2,3,4]
    >>> l2 = l1
    >>> l2[0] = 5
    >>> l1
    [5, 2, 3, 4]
    >>> l2 = l1.copy()
    >>> l1
    [5, 2, 3, 4]
    >>> l2
    [5, 2, 3, 4]
    >>> l2[0]=10
    >>> l1
    [5, 2, 3, 4]
    >>> l2
    [10, 2, 3, 4]
  • count():计算某个元素在列表出现的次数

    >>> l = [1,1,2,3,1,2,3,4,3,2,1,1,2]
    >>> l.count(2)
    4
  • extend():将其他列表的内容扩展到当前列表中(将后者内部所有的元素依次添加在当前列表中)

    >>> l1 = [1,2,3,4]
    >>> l2 = [5,6,7,8]
    >>> l1.extend(l2)
    >>> l1
    [1, 2, 3, 4, 5, 6, 7, 8]
    >>> l2
    [5, 6, 7, 8]
    >>> l1.extend("abc")
    >>> l1
    [1, 2, 3, 4, 5, 6, 7, 8, 'a', 'b', 'c']
    >>> l1.extend(123)
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    TypeError: 'int' object is not iterable
    
    #如何理解extend?
    lst = []
    def extend(lter):
        for i in Iter:
            lst.append(i)

    不同于两个序列相加,两个序列相加,是直接创建新的序列对象的

  • index():从左到右返回元素的角标,如果不存在则抛出异常

    >>> l = [1,2,3,4]
    >>> l.index(3)
    2
    >>> l.index(5)
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    ValueError: 5 is not in list
    ​
    >>> l.find(3)
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    AttributeError: 'list' object has no attribute 'find'
  • insert():在某个位置插入元素,角标如果越界,如果是负数,则为倒数第几个;如果角标大于列表长度,在末尾添加

    >>> l
    [1, 2, 3, 4]
    >>> l.insert(2,5)
    >>> l
    [1, 2, 5, 3, 4]
    >>> l.insert(10,6)
    >>> l
    [1, 2, 5, 3, 4, 6]
    >>> l.insert(-2,7)
    >>> l
    [1, 2, 5, 3, 7, 4, 6]
  • pop():在列表的尾部删除一个元素,弹栈;append理解为进栈

    >>> l = [1,2,3,4]
    >>> l.append(5)
    >>> l
    [1, 2, 3, 4, 5]
    >>> l.pop()
    5
    >>> l
    [1, 2, 3, 4]
  • remove():删除从左到右第一个指定的元素

    >>> l
    [1, 2, 3, 4]
    >>> l.remove(4)
    >>> l
    [1, 2, 3]
    >>> l.remove(2)
    >>> l
    [1, 3]
    >>> l = [1,1,1,2,2,3,3]
    >>> l.remove(1)
    >>> l
    [1, 1, 2, 2, 3, 3]
  • reverse():反转列表

    >>> l.reverse()
    >>> l
    [3, 3, 2, 2, 1, 1]
  • sort():排序

    >>> l = [3,2,9,1,6,5,7,4,8]
    >>> l.sort()
    >>> l
    [1, 2, 3, 4, 5, 6, 7, 8, 9]
    >>> l.reverse()
    >>> l
    [9, 8, 7, 6, 5, 4, 3, 2, 1]

列表解析式

是通过for循环语句来创建列表

>>> l1 = [1,2,3,4,5,6,7,8,9,10]
>>> l1 = list(range(1,11))
>>> l1
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
>>> l1 = [x for x in range(1,11)]
>>> l1
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
>>> l1 = [x for x in range(1,21) if x%3==0 ]
>>> l1
[3, 6, 9, 12, 15, 18]
>>> l2 = [x/2 for x in l1]
>>> l2
[1.5, 3.0, 4.5, 6.0, 7.5, 9.0]

二分查找算法

前提是我们的序列必须有序的(递增,递减)

# 二分查找
def binarySearch(lst, key):
    min_index = 0
    max_index = len(lst) - 1
    mid_index = (min_index + max_index) // 2
    while lst[mid_index] != key:
        if lst[mid_index] < key:
            min_index = mid_index + 1
        elif lst[mid_index] > key:
            max_index = mid_index - 1
        if min_index > max_index:
            return -1
        mid_index = (min_index + max_index) // 2
    return mid_index
​
lst = [x for x in range(1,13)]
print(binarySearch(lst,9))
print(binarySearch(lst,1))
print(binarySearch(lst,8.5))
print(binarySearch(lst,15))
lst = [x ** 2 for x in range(1,13)]
print(binarySearch(lst,121))
print(binarySearch(lst,120))

选择排序算法

def selectionSort(lst):
    for i in range(len(lst) - 1):
        for j in range(i+1,len(lst)):
            if lst[i] > lst[j]:
                lst[i],lst[j] = lst[j],lst[i]
                """
                temp = lst[i]
                lst[i] = lst[j]
                lst[j] = temp
                """
lst = [5,1,9,8,2,6,7,4,3]
selectionSort(lst)
print(lst)
 

冒泡排序算法

def bubbleSort(lst):
    for i in range(len(lst) - 1):
        for j in range(len(lst) - 1 - i):
            if lst[j] > lst[j + 1]:
                lst[j], lst[j + 1] = lst[j + 1], lst[j]
lst = [5,1,9,8,2,6,7,4,3]
bubbleSort(lst)
print(lst)

插入排序算法

def insertionSort(lst):
    for i in range(1,len(lst)):
        e = lst[i]
        j = i
        while j > 0 and lst[j - 1] > e:
            lst[j] = lst[j - 1]
            j -= 1
        lst[j] = e
lst = [5,1,9,8,2,6,7,4,3]
insertionSort(lst)
print(lst)

计数排序算法

def countingSort(lst):
    minVal = min(lst)
    maxVal = max(lst)
    temp = [0] * (maxVal - minVal + 1)
    offset = minVal
    for number in lst:
        temp[number - offset] += 1
    i = 0
    for index in range(len(temp)):
        for k in range(temp[index]):
            lst[i] = index + offset
            i += 1
​
lst = [5,1,9,8,2,6,7,4,3]
countingSort(lst)
print(lst)

基数排序算法

import random
def getIndex(num,r):
    if len(str(num)) < r:
        return 0
    return int(str(num)[-r])
​
def radixSort(lst):
    maxVal = max(lst)
    radix = len(str(maxVal))
    temp = [None] * 10
    for i in range(10):
        temp[i] = []
​
    # 1个位 2十位 3百位
    for r in range(1,radix + 1):
        for num in lst:
            temp[getIndex(num,r)].append(num)
        i = 0
        for k in range(len(temp)):
            if len(temp[k]) != 0:
                for j in range(len(temp[k])):
                    lst[i] = temp[k][j]
                    i += 1
                temp[k].clear()
lst = []
for i in range(20):
    lst.append(random.randint(1,300))
radixSort(lst)
print(lst)

元组

和列表一样是序列的一种,是用圆括号括起来的()

元组是一种不可变序列,可以理解为不可变的列表

除了内部元素不能修改(增,删,改)之外,其他的和列表用法差不多

>>> t = ()
>>> type(t)
<class 'tuple'>
>>> t = (1)
>>> type(t)
<class 'int'>
>>> t = (1,)
>>> type(t)
<class 'tuple'>
>>> t = (1,2,3)
>>> type(t)
<class 'tuple'>
>>> t = 1,2,3,4,5
>>> type(t)
<class 'tuple'>
>>> t = "你好","世界","哈哈"
>>> type(t)
<class 'tuple'>
>>> l = [1,2,3,4,5]
>>> type(l)
<class 'list'>
>>> t = tuple(l)
>>> t
(1, 2, 3, 4, 5)
>>> t = tuple("abcde")
>>> t
('a', 'b', 'c', 'd', 'e')

元素与列表相同的操作

  • count()、index()

  • len()、max()、min()、tuple()

>>> t = (1,2,3,4,5)
>>> max(t)
5
>>> min(t)
1
>>> len(t)
5
>>> t.count(5)
1
>>> t.index(3)
2
>>> t.sort()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'tuple' object has no attribute 'sort'
>>> t.find(3)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'tuple' object has no attribute 'find'

元组中不允许的操作

  • 修改、新增元素

  • 删除某个元素(但是可以删除整个元组)

  • 所有会对元组内部元素发生修改动作的方法

>>> t.append(1)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'tuple' object has no attribute 'append'
>>> t.remove(2)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'tuple' object has no attribute 'remove'
>>> t
(1, 2, 3, 4, 5)
>>> t[0] = 666
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'tuple' object does not support item assignment
>>> del t[0]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'tuple' object doesn't support item deletion
>>> del t
>>> t
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 't' is not defined

元组只保证它的一级子元素不可变,对于嵌套的元素内部,不保证不可变的

说白了指的就是元组所存储的对象地址不可变

>>> t = (1,2,[3,4])
>>> t[0] = 666
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'tuple' object does not support item assignment
>>> t[2] = [5,6]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'tuple' object does not support item assignment
>>> t[2][0] = 5
>>> t[2][1] = 6
>>> t
(1, 2, [5, 6])
>>> id(t[2])
53493544
>>> t[2].append(7)
>>> t
(1, 2, [5, 6, 7])
>>> id(t[2])
53493544

所以,在使用元组时,尽量使用数字、字符串和元组这种不可变对象的数据类型作为元素

一般什么时候去使用?当数据一旦确定下来,不可更改时,则使用

>>> address = ("172.16.20.222","8080") # IP地址与端口号绑定

 

猜你喜欢

转载自blog.csdn.net/trichloromethane/article/details/108267507
今日推荐