欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

Python 列表与元组

程序员文章站 2022-06-30 18:29:46
本节导航: List 列表: 增 删 查 改 其他 列表的循环 Tuple 元组 List 列表: 增 删 查 改 其他 列表的循环 Tuple 元组 一、List 列表 列表(list)属于一种有序的集合,可以随时添加和删除其中的元素。列表是 Python 中内置的一种数据类型,也是最常用的 Py ......

 本节导航:


一、List 列表

  列表(list)属于一种有序的集合,可以随时添加和删除其中的元素。列表是 Python 中内置的一种数据类型,也是最常用的 Python 数据类型。列表的命名规则就是一个方括号([]),创建一个列表只要把逗号分隔的不同的数据项使用方括号括起来即可。列表中每个元素都分配有一个数字(从0开始),这个数字即为该元素的位置(或索引)也可以认为是该元素的下标,第一个索引是0,第二个索引是1,反过来最后一个索引是-1,依此类推。

  在这里我们就简单声明一个班级名单列表 name 进行演示:

name = ["Madonna", "Cory", "Annie", "Nelly"]

注:列表中的数据项可以为任意数据类型。

Python 列表与元组

   现在我们已经弄清楚列表元素的具体位置了,也顺便建立了一个简单的列表,那下面就让我们详细的了解下列表到底有哪些方法吧。

“增”在单个列表添加元素时不能批量的插入元素,只能一个一个的来,具体的方法有 append() insert() 两种方法。append() 是直接在原列表的末尾追加(添加)元素,而 insert() 是在添加的索引前面插入(添加)元素;当在涉及两个或两个以上列表时,列表的内置方法中还提供了一种 extend() ,可以把另一个列表的所以元素追加到原列表(尾部追加)。演示实例如下:

name = ["Madonna", "Cory", "Annie", "Nelly"]        #创建一个班级名单列表 name

name.append("Eleanor")          #在name列表末尾追加 "Eleanor"
print(name)                     #['Madonna', 'Cory', 'Annie', 'Nelly', 'Eleanor']

name.insert(1, "Baade")         #在原索引为1的元素前面添加 "Baade",即 "Baade" 占据原为索引为1的位置
print(name)                     #['Madonna', 'Baade', 'Cory', 'Annie', 'Nelly', 'Eleanor']

b = [1, 2, 3]                   #创建一个新的列表 b
name.extend(b)                  #把 b 列表整个追加到 name 列表后
print(name)                     #['Madonna', 'Baade', 'Cory', 'Annie', 'Nelly', 'Eleanor', 1, 2, 3]
Python 列表与元组
    def append(self, p_object): # real signature unknown; restored from __doc__
        """ L.append(object) -> None -- append object to end """
        pass

    def insert(self, index, p_object): # real signature unknown; restored from __doc__
        """ L.insert(index, object) -- insert object before index """
        pass

    def extend(self, iterable): # real signature unknown; restored from __doc__
        """ L.extend(iterable) -> None -- extend list by appending elements from the iterable """
        pass
append() insert() extend() 部分源代码

“删”:Python中提供了三种相关的内置方法和一种通用的删除方法。remove() :确定要删除的对象后,删除第一次出现的值,如果值不存在,就会引发ValueError错误;pop() :输入下标后,删除指定位置的元素,如果列表为空或索引超出范围,则会引发IndexError错误;clear() :直接清空列表;del:可以通过指定索引位置删除列表中所对应的元素,也可以直接删除列表。

name = ["Madonna", "Cory", "Annie", "Nelly", "Cory"]        #创建一个班级名单列表 name
name.remove("Cory")             #移除从左边数第一个 "Cory" 元素
print(name)                     #['Madonna', 'Annie', 'Nelly', 'Cory']

name = ["Madonna", "Cory", "Annie", "Nelly", "Cory"]
name.pop()                      #默认删除列表的最后一位元素
print(name)                     #['Madonna', 'Cory', 'Annie', 'Nelly']
name.pop(0)                     #指定删除列表中的第一个元素,相当于 del
print(name)                     #['Cory', 'Annie', 'Nelly']

name = ["Madonna", "Cory", "Annie", "Nelly", "Cory"]
del name[2]                     # 删除列表中的第二个元素
print(name)                     #['Madonna', 'Cory', 'Nelly', 'Cory']

name.clear()                    #清空列表
print(name)                     #[]

del name                        #删除列表
print(name)                     #NameError: name 'name' is not defined

注:pop() 方法不加索引位置时默认删除列表的最后一位,输入下标(索引位置)后,删除指定位置的元素。

Python 列表与元组
    def remove(self, value): # real signature unknown; restored from __doc__
        """
        L.remove(value) -> None -- remove first occurrence of value.
        Raises ValueError if the value is not present.
        """
        pass

    def pop(self, index=None): # real signature unknown; restored from __doc__
        """
        L.pop([index]) -> item -- remove and return item at index (default last).
        Raises IndexError if list is empty or index is out of range.
        """
        pass

    def clear(self): # real signature unknown; restored from __doc__
        """ L.clear() -> None -- remove all items from L """
        pass
remove() pop() clear() 部分源代码

“查”:可以分为两种情况,一种情况是想中知道单个索引或一个索引到另一个索引所对应的元素,这时候直接用列表名加方括号的方式获取,我们可以把这种情况说成是列表的切片,即获取列表中对应索引的元素(通俗来讲就是把列表中的部分内容取出来);另外一种情况是知道列表中的某个元素,想要查询该元素所在的索引位置,在这种情况下我们就需要利用内置的 index() 来实现了。演示实例如下:

name = ["Madonna", "Cory", "Annie", "Nelly"]        #创建一个班级名单列表 name

print(name[0])          #Madonna      取列表的第一个元素
print(name[3])          #Nelly       取列表的第四个元素
print(name[-1]) #Nelly       取列表的最后一个元素
print(name[0:2])           #['Madonna', 'Cory']        取列表第一个到第二个元素
print(name[:2])          #['Madonna', 'Cory']        取列表第一个到第二个元素
print(name[0:-1])        #['Madonna', 'Cory', 'Annie']          取列表第一个到三个元素
print(name[1:])      #['Cory', 'Annie', 'Nelly'] 取列表第二个到最后一个元素
print(name[-3:-1]) #['Cory', 'Annie'] 取列表第二个到第三个元素
print(name[:]) #['Madonna', 'Cory', 'Annie', 'Nelly'] 取列表第一个到最后一个元素

print(name.index("Cory")) #1 查询 Cory 元素所在的索引位置
print(name.index("Nelly")) #3 查询 Nelly 元素所在的索引位置

 注:

  • 1、方括号的切片原则是“顾头不顾尾”,当查找单个索引所对应的元素时直接方括号内加索引位置即可;当查找一个索引到另一个索引所对应的元素时,在方括号内写入索引位置中间用冒号(:)隔开;
  • 2、当输入的索引位置为 0 -1 时,可以省略,尤其是省略 -1时包含 -1 所对应的最后一个元素,不省略的话不包括最后一个元素;
  • 3、切片是从左往右取,如果是 name[-1:-3] 则取不到值,为空,正确写法为 name[-3:-1]
Python 列表与元组
    def index(self, value, start=None, stop=None): # real signature unknown; restored from __doc__
        """
        L.index(value, [start, [stop]]) -> integer -- return first index of value.
        Raises ValueError if the value is not present.
        """
        return 0
index() 部分源代码

“改”是最简单的也是最直接的,直接通过赋值修改对应索引位置的元素即可。演示实例如下:

name = ["Madonna", "Cory", "Annie", "Nelly"]        #创建一个班级名单列表 name

name[0] = "Ayris"           #把 "Ayris" 元素赋值给name列表中的 0 索引位置,即把0索引位置的元素改为 "Ayris"
print(name)                 #['Ayris', 'Cory', 'Annie', 'Nelly']
print(name[0])              #Ayris

其他:count()  :在列表中统计某个元素出现的次数;reverse()  :反转列表元素;sort()  :把列表元素按ASCII码排序;

name = ["Madonna", "Cory", "Annie", "Nelly", "Cory"]        #创建一个班级名单列表 name

print(name.count("Cory"))           #2    在列表中统计 "Cory" 元素出现的次数

name.reverse()                      #反转列表
print(name)                         #['Cory', 'Nelly', 'Annie', 'Cory', 'Madonna']

name.sort()                         #按ASCII码排序
print(name)                         #['Annie', 'Cory', 'Cory', 'Madonna', 'Nelly']
Python 列表与元组
    def count(self, value): # real signature unknown; restored from __doc__
        """ L.count(value) -> integer -- return number of occurrences of value """
        return 0

   def reverse(self): # real signature unknown; restored from __doc__
        """ L.reverse() -- reverse *IN PLACE* """
        pass

    def sort(self, key=None, reverse=False): # real signature unknown; restored from __doc__
        """ L.sort(key=None, reverse=False) -> None -- stable sort *IN PLACE* """
        pass
count() reverse() sort() 部分源代码

  “浅copy“深copy”的探究:copy () 又称浅copy,在列表复制中只固定列表的第一层,如果原列表内镶嵌多层时,如果修改原列表的深层(大于一层)时,copy的新列表的深层也会跟着发生变换,第二个列表的内容(每一个元素)只是第一个列表内容的引用;copy.deepcopy() 我们称之为深copy,即全部复制原列表,复制好后的列表和新列表变成两个完全独立的列表,互不干扰。

import copy         #导入 copy 模块

name = ["Madonna", "Cory", ["Annie", "Nelly"], "Cory"]        #创建一个班级名单列表 name

b = name.copy()                 #浅copy,复制成新的列表 b
c = copy.deepcopy(name)         #深copy,复制成新的列表 c
print(b)                        #['Madonna', 'Cory', ['Annie', 'Nelly'], 'Cory']
print(c)                        #['Madonna', 'Cory', ['Annie', 'Nelly'], 'Cory']

del name[1]                     #删除原列表中的第二个元素
print(name)                     #['Madonna', ['Annie', 'Nelly'], 'Cory']
print(b)                        #['Madonna', 'Cory', ['Annie', 'Nelly'], 'Cory']
print(c)                        #['Madonna', 'Cory', ['Annie', 'Nelly'], 'Cory']

del name[1][1]                  #删除第二个元素后,在新列表中删除第一个二个元素(列表元素)中的第一个元素
print(name)                     #['Madonna', ['Annie'], 'Cory']
print(b)                        #['Madonna', 'Cory', ['Annie'], 'Cory']
print(c)                        #['Madonna', 'Cory', ['Annie', 'Nelly'], 'Cory']
Python 列表与元组
     def copy(self): # real signature unknown; restored from __doc__
        """ L.copy() -> list -- a shallow copy of L """
        return []

def deepcopy(x, memo=None, _nil=[]):
    """Deep copy operation on arbitrary Python objects.

    See the module's __doc__ string for more info.
    """

    if memo is None:
        memo = {}

    d = id(x)
    y = memo.get(d, _nil)
    if y is not _nil:
        return y

    cls = type(x)

    copier = _deepcopy_dispatch.get(cls)
    if copier:
        y = copier(x, memo)
    else:
        try:
            issc = issubclass(cls, type)
        except TypeError: # cls is not a class (old Boost; see SF #502085)
            issc = 0
        if issc:
            y = _deepcopy_atomic(x, memo)
        else:
            copier = getattr(x, "__deepcopy__", None)
            if copier:
                y = copier(memo)
            else:
                reductor = dispatch_table.get(cls)
                if reductor:
                    rv = reductor(x)
                else:
                    reductor = getattr(x, "__reduce_ex__", None)
                    if reductor:
                        rv = reductor(4)
                    else:
                        reductor = getattr(x, "__reduce__", None)
                        if reductor:
                            rv = reductor()
                        else:
                            raise Error(
                                "un(deep)copyable object of type %s" % cls)
                if isinstance(rv, str):
                    y = x
                else:
                    y = _reconstruct(x, memo, *rv)

    # If is its own copy, don't memoize.
    if y is not x:
        memo[d] = y
        _keep_alive(x, memo) # Make sure x lives at least as long as d
    return y
copy() copy.deepcopy() 部分源代码

  列表的循环:我们实现列表的循环可以使用两种方法,第一种直接使用循环语句实现每个元素的打印效果,打印的结果不是列表了而是一个一个单独的元素;第二种仿照简单的 for 循环结构进行打印,可以实现跳跃打印,打印的结果还是一个列表。(循环语句我们会在以后的话题中谈到)

name = ["Madonna", "Cory", ["Annie", "Nelly"], "Cory"]        #创建一个班级名单列表 name

for i in name:          #for 循环打印列表的元素
    print(i)            #Madonna    Cory    ['Annie', 'Nelly']  Cory

print(name[::])         #['Madonna', 'Cory', ['Annie', 'Nelly'], 'Cory']
print(name[0:3:1])      #['Madonna', 'Cory', ['Annie', 'Nelly']]
print(name[::2])        #['Madonna', ['Annie', 'Nelly']]

  通过 len() 函数获取列表元素的个数。

name = ["Madonna", "Cory", ["Annie", "Nelly"], "Cory"]        #创建一个班级名单列表 name

print(len(name))            #4

二、Tuple 元组

  元组和列表差不多,我们可以把元组看成是简单的只读列表,与“强大”的列表不同的是,元组创建后其中的元素就不能被修改了,它只有两个内置的方法:index() count() ,可以像列表那样进行“查”(即进行切片)和count() 统计,不支持复杂的“增”、“删”、“改”等功能。元组创建很简单,只需要在小括号中添加元素,并使用逗号隔开即可。具体的操作请查看上文列表,这里就不进行详细的说明,简单演示实例如下:

name = ["Madonna", "Cory", ["Annie", "Nelly"], "Cory"]        #创建一个班级名单列表 name

name_1 = ("Madonna", "Cory", ["Annie", "Nelly"], "Cory")      #创建一个班级名单元组 name_1
print(name_1)               #('Madonna', 'Cory', ['Annie', 'Nelly'], 'Cory')

print(name_1[1:3])                  #('Cory', ['Annie', 'Nelly'])
print(name_1.index("Madonna"))      #0

print(len(name_1))                  #4

注:单个括号 ()  即可表示元组,又可以表示数学公式中的小括号,打印时会产生歧义,所以当定义单个单独的元素时,元素后必须要加一个逗号(,)隔开。

a = ("name")
print(a)                #name
print(type(a))          #<class 'str'>
b = (1)
print(b)                #1
print(type(b))          #<class 'int'>
c = ("name",)
print(c)                #('name',)
print(type(c))          #<class 'tuple'>
d = (1,)
print(d)                #(1,)
print(type(d))          #<class 'tuple'>

补充:当更深层次的涉猎元组时我们就会发现,当元组的内部定义一个列表元素时,我们可以改变这个列表元素中的元素,这样一来元组的内容就发生了改变,这不就与我们上文中所提及的“元组不变”相矛盾吗?

  其实并不是这样的,元组中所谓的“不变”是指元素的指向不发生改变,即指向一个列表后就不能指向其他对象了,在元组中的整个列表合起来属于一个元组元素,元组指向这个列表后就不会指向其他对象了。在列表内容中我们就已经知道列表是可变的,当定义在元组内部时其可变的性质是不会随之发生改变的,所以这个发生改变的是元组内部的列表。

a = (1, 2, 3, ["one", "two"])       #创建一个元组 a

a[3][0] = "first"       #把列表中的第一个元素改为 first
a[3][1] = "second"      #把列表中的第二个元素改为 second

print(a)                #(1, 2, 3, ['first', 'second'])