python列表嵌套引发的问题总结

目录
  • 1.嵌套列表
  • 2.识别坑点
  • 3.区分两个概念
  • 4.小例子
  • 5.正确代码
  • 总结

1.嵌套列表

Python中有一种内置的数据类型叫列表(list),它是一种容器,可以用来承载其他的对象(准确的说是其他对象的引用),列表中的对象可以称为列表的元素,很明显我们可以把列表作为列表中的元素,这就是所谓的嵌套列表。

嵌套列表可以模拟出现实中的表格、矩阵、2D游戏的地图(如植物大战僵尸的花园)、棋盘(如国际象棋、黑白棋)等。

2.识别坑点

在使用嵌套的列表时要小心,否则很可能遭遇非常尴尬的情况,下面是一个小例子:

def main():
names = ['关羽', '张飞', '赵云', '马超', '黄忠']
subjs = ['语文', '数学', '英语']
scores = [[0] * 3] * 5
for row, name in enumerate(names):
print('请输入%s的成绩' % name)
for col, subj in enumerate(subjs):
scores[row][col] = float(input(subj + ': '))
print(scores)
if __name__ == '__main__':
main()

我们希望录入5个学生3门课程的成绩,于是定义了一个有5个元素的列表,而列表中的每个元素又是一个由3个元素构成的列表,这样一个列表的列表刚好跟一个表格是一致的,相当于有5行3列。

接下来我们通过嵌套的for-in循环输入每个学生3门课程的成绩。程序执行完成后我们发现,每个学生3门课程的成绩是一模一样的(尴尬),而且就是最后录入的那个学生的成绩。

3.区分两个概念

要想把这个坑填平,我们首先要区分对象和对象的引用这两个概念,而要区分这两个概念,还得先说说内存中的栈和堆。

我们经常会听人说起“堆栈”这个词,但实际上“堆”和“栈”是两个不同的概念。众所周知,一个程序运行时需要占用一些内存空间来存储数据和代码,那么这些内存从逻辑上又可以做进一步的划分。

对底层语言(如C语言)有所了解的程序员大都知道,程序中可以使用的内存从逻辑上可以为五个部分,按照地址从高到低依次是:栈(stack)、堆(heap)、数据段(data segment)、只读数据段(static area)和代码段(code segment)。

栈用来存储局部、临时变量,以及函数调用时保存现场和恢复现场需要用到的数据,这部分内存在代码块开始执行时自动分配,代码块执行结束时自动释放,通常由编译器自动管理。

堆的大小不固定,可以动态的分配和回收,因此如果程序中有大量的数据需要处理,这些数据通常都放在堆上,如果堆空间没有正确的被释放会引发内存泄露的问题,而像Python、Java等编程语言都使用了垃圾回收机制来实现自动化的内存管理(自动回收不再使用的堆空间)。

4.小例子

所以,下面的代码中,变量a并不是真正的对象,它是对象的引用,相当于记录了对象在堆空间的地址,通过这个地址我们可以访问到对应的对象。

a = object()
b = ['apple', 'pitaya', 'grape']

同理,变量b是列表容器的引用,它引用了堆空间上的列表容器,而列表容器中并没有保存真正的对象,它保存的也仅仅是对象的引用。

知道了这一点,我们可以回过头看看刚才的程序,我们对列表进行[[0]* 3] * 5操作时,仅仅是将[0, 0, 0] 这个列表的地址进行了复制,并没有创建新的列表对象。

所以,容器中虽然有5个元素,但是这5个元素引用了同一个列表对象。这一点可以通过id函数检查scores[0]和scores[1]的地址得到证实。在此我们举一个小例子,读者朋友们可以敲一敲加深印象。

a = [[0]*3]*5id(a[0])
id(a[1])
# id相等

5.正确代码

所以,正确的代码应该按照如下的方式进行修改:

def main():
names = ['关羽', '张飞', '赵云', '马超', '黄忠']
subjs = ['语文', '数学', '英语']
scores = [[]] * 5
for row, name in enumerate(names):
print('请输入%s的成绩' % name)
scores[row] = [0] * 3 #变为不再嵌套
for col, subj in enumerate(subjs):
scores[row][col] = float(input(subj + ': '))
print(scores)
if __name__ == '__main__':
main()

或者:

def main():
names = ['关羽', '张飞', '赵云', '马超', '黄忠']
subjs = ['语文', '数学', '英语']
scores = [[0] * 3 for _ in range(5)]
for row, name in enumerate(names):
print('请输入%s的成绩' % name)
scores[row] = [0] * 3
for col, subj in enumerate(subjs):
scores[row][col] = float(input(subj + ': '))
print(scores)
if __name__ == '__main__':
main()

总结

本文介绍使用嵌套列表需要注意的问题及解决措施,以此避免在使用嵌套列表或者复制对象时可能遇到的坑。

到此这篇关于python列表嵌套引发的问题总结的文章就介绍到这了,更多相关python列表嵌套内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • python中字典和列表的相互嵌套问题详解

    目录 1.列表中存储字典: 1.列表中存储多个字典 2.访问列表中字典的值 3.遍历访问多个值 2.字典中存储列表 1.访问字典中的列表元素 2.访问字典中的值(字典中的值为列表) 3.字典中存储字典 1.字典中不能全部由字典元素组成,会报错. 2.字典中的值可由字典组成 4.容易出的小错误: 总结 首先明确: 1.访问字典中的元素:dict_name[key] / dict_name.get(key) 2.访问列表中的元素:list_name[索引] 1.列表中存储字典: 1.列表中存储多个字

  • 浅谈Python列表嵌套字典转化的问题

    在看视频教程的时候提到了[{'a' : 97}, {'b' : 98}, {'c' : 99}, {'d' : 100}, {'e' : 101}, ...........]形式的列表嵌套形式, 要求是将上述列表转换为{'a' : 97,'b' : 98,'c' : 99 ,'d' : 100,'e' : 101,.....}的字典形式 首先上述的a--->97, b--->98,.....意思是key为a到z的英文小写字母,value值为对应的ascii码, 那么一开始可以结合range()

  • python列表嵌套引发的问题总结

    目录 1.嵌套列表 2.识别坑点 3.区分两个概念 4.小例子 5.正确代码 总结 1.嵌套列表 Python中有一种内置的数据类型叫列表(list),它是一种容器,可以用来承载其他的对象(准确的说是其他对象的引用),列表中的对象可以称为列表的元素,很明显我们可以把列表作为列表中的元素,这就是所谓的嵌套列表. 嵌套列表可以模拟出现实中的表格.矩阵.2D游戏的地图(如植物大战僵尸的花园).棋盘(如国际象棋.黑白棋)等. 2.识别坑点 在使用嵌套的列表时要小心,否则很可能遭遇非常尴尬的情况,下面是一

  • Python列表嵌套常见坑点及解决方案

    1.嵌套列表 Python中有一种内置的数据类型叫列表(list),它是一种容器,可以用来承载其他的对象(准确的说是其他对象的引用),列表中的对象可以称为列表的元素,很明显我们可以把列表作为列表中的元素,这就是所谓的嵌套列表. 嵌套列表可以模拟出现实中的表格.矩阵.2D游戏的地图(如植物大战僵尸的花园).棋盘(如国际象棋.黑白棋)等. 2.识别坑点 在使用嵌套的列表时要小心,否则很可能遭遇非常尴尬的情况,下面是一个小例子. def main(): names = ['关羽', '张飞', '赵云

  • PYTHON压平嵌套列表的简单实现

    list 是 Python 中使用最频繁的数据类型, 标准库里面有丰富的函数可以使用. 不过,如果把多维列表转换成一维列表(不知道这种需求多不多),还真不容易找到好用的函数, 要知道Ruby.Mathematica.Groovy中可是有flatten的啊. 如果列表是维度少的.规则的,还算好办 例如: li=[[1,2],[3,4],[5,6]] print [j for i in li for j in i] #or from itertools import chain print list

  • Python实现嵌套列表及字典并按某一元素去重复功能示例

    本文实例讲述了Python实现嵌套列表及字典并按某一元素去重复功能.分享给大家供大家参考,具体如下: #! /usr/bin/env python #coding=utf-8 class HostScheduler(object): def __init__(self, resource_list): self.resource_list = resource_list def MergeHost(self): allResource=[] allResource.append(self.res

  • Python实现嵌套列表去重方法示例

    发现问题 python嵌套列表大家应该都不陌生,但最近遇到了一个问题,这是工作中遇到的一个坑,首先看一下问题 raw_list = [["百度", "CPY"], ["京东", "CPY"], ["黄轩", "PN"], ["百度", "CPY"]] 列表嵌套了列表,并且有一个重复列表["百度", "CPY"

  • python实现嵌套列表平铺的两种方法

    方法一:使用列表推导式 >>> vec = [[1,2,3],[4,5,6],[7,8,9]] >>> get = [num for elem in vec for num in elem] >>> get [1, 2, 3, 4, 5, 6, 7, 8, 9] 方法相当于 >>> vec = [[1,2,3],[4,5,6],[7,8,9]] >>> result = [] >>> for ele

  • python列表切片和嵌套列表取值操作详解

    给出列表切片的格式: [开头元素::步长] # 输出直到最后一个元素,(最后一个冒号和步长可以省略,下同) [开头元素:结尾元素(不含):步长] # 其中,-1表示list最后一个元素 首先来看最简单的单一列表: a = [1,2,3,4] a[:] a[::] a[:3] a[1:3:2] a[3] 输出依次为: [1,2,3,4] [1,2,3,4] [1,2,3] [2] 4 注意,这里只有最后一个输出是不带[]的,表明只有最后一个输出是元素,其他在切片中只用了:符号的输出均为list,不

  • python 字典和列表嵌套用法详解

    python中字典和列表的使用,在数据处理中应该是最常用的,这两个熟练后基本可以应付大部分场景了.不过网上的基础教程只告诉你列表.字典是什么,如何使用,很少做组合说明. 刚好工作中采集prometheus监控接口并做数据处理的时候,用了很多组合场景,列出几个做一些分享. 列表(List) 序列是Python中最基本的数据结构.序列中的每个元素都分配一个数字 - 它的位置,或索引,第一个索引是0,第二个索引是1,依此类推. 列表是最常用的Python数据类型,它可以作为一个方括号内的逗号分隔值出现

  • 如何利用python实现列表嵌套字典取值

    目录 一.实例 二.解决思路 三.代码示例 一.实例 将以下列表的backup_unit_id全部提取出来 示例: dbs = [{         "backup_unit_id": 163,         "data_node_id": 2,         "attribute": {             "convertor_id": 4,             "channel_num":

随机推荐