A. python如下报错是什么意思
要把代码发现来才知道,以下是常见的错误
下面终于要讲到当你用到更多的Python的功能(数据类型,函数,模块,类等等)时可能碰到的问题了。由于篇幅有限,这里尽量精简,尤其是对一些高级的概念。要想了解更多的细节,敬请阅读Learning Python, 2nd Edition的“小贴士”以及“Gotchas”章节。
打开文件的调用不使用模块搜索路径
当你在Python中调用open()来访问一个外部的文件时,Python不会使用模块搜索路径来定位这个目标文件。它会使用你提供的绝对路径,或者假定这个文件是在当前工作目录中。模块搜索路径仅仅为模块加载服务的。
不同的类型对应的方法也不同
列表的方法是不能用在字符串上的,反之亦然。通常情况下,方法的调用是和数据类型有关的,但是内部函数通常在很多类型上都可以使用。举个例子来说,列表的reverse方法仅仅对列表有用,但是len函数对任何具有长度的对象都适用
不能直接改变不可变数据类型
记住你没法直接的改变一个不可变的对象(例如,元组,字符串):
T = (1, 2, 3)
T[2] = 4 # 错误
用切片,联接等构建一个新的对象,并根据需求将原来变量的值赋给它。因为Python会自动回收没有用的内存,因此这没有看起来那么浪费:
T = T[:2] + (4,) # 没问题了: T 变成了 (1, 2, 4)
使用简单的for循环而不是while或者range
当你要从左到右遍历一个有序的对象的所有元素时,用简单的for循环(例如,for x in seq:)相比于基于while-或者range-的计数循环而言会更容易写,通常运行起来也更快。除非你一定需要,尽量避免在一个for循环里使用range:让Python来替你解决标号的问题。在下面的例子中三个循环结构都没有问题,但是第一个通常来说更好;在Python里,简单至上。
S = "lumberjack"
for c in S: print c # 最简单
for i in range(len(S)): print S[i] # 太多了
i = 0 # 太多了
while i < len(S): print S[i]; i += 1
不要试图从那些会改变对象的函数得到结果
诸如像方法list.append()和list.sort()一类的直接改变操作会改变一个对象,但不会将它们改变的对象返回出来(它们会返回None);正确的做法是直接调用它们而不要将结果赋值。经常会看见初学者会写诸如此类的代码:
mylist = mylist.append(X)
目的是要得到append的结果,但是事实上这样做会将None赋值给mylist,而不是改变后的列表。更加特别的一个例子是想通过用排序后的键值来遍历一个字典里的各个元素,请看下面的例子:
D = {...}
for k in D.keys().sort(): print D[k]
差一点儿就成功了——keys方法会创建一个keys的列表,然后用sort方法来将这个列表排序——但是因为sort方法会返回None,这个循环会失败,因为它实际上是要遍历None(这可不是一个序列)。要改正这段代码,将方法的调用分离出来,放在不同的语句中,如下:
Ks = D.keys()
Ks.sort()
for k in Ks: print D[k]
只有在数字类型中才存在类型转换
在Python中,一个诸如123+3.145的表达式是可以工作的——它会自动将整数型转换为浮点型,然后用浮点运算。但是下面的代码就会出错了:
S = "42"
I = 1
X = S + I # 类型错误
这同样也是有意而为的,因为这是不明确的:究竟是将字符串转换为数字(进行相加)呢,还是将数字转换为字符串(进行联接)呢?在Python中,我们认为“明确比含糊好”(即,EIBTI(Explicit is better than implicit)),因此你得手动转换类型:
X = int(S) + I # 做加法: 43
X = S + str(I) # 字符串联接: "421"
循环的数据结构会导致循环
尽管这在实际情况中很少见,但是如果一个对象的集合包含了到它自己的引用,这被称为循环对象(cyclic object)。如果在一个对象中发现一个循环,Python会输出一个[…],以避免在无限循环中卡住:
>>> L = ['grail'] # 在 L中又引用L自身会
>>> L.append(L) # 在对象中创造一个循环
>>> L
['grail', [...]]
除了知道这三个点在对象中表示循环以外,这个例子也是很值得借鉴的。因为你可能无意间在你的代码中出现这样的循环的结构而导致你的代码出错。如果有必要的话,维护一个列表或者字典来表示已经访问过的对象,然后通过检查它来确认你是否碰到了循环。
赋值语句不会创建对象的副本,仅仅创建引用
这是Python的一个核心理念,有时候当行为不对时会带来错误。在下面的例子中,一个列表对象被赋给了名为L的变量,然后L又在列表M中被引用。内部改变L的话,同时也会改变M所引用的对象,因为它们俩都指向同一个对象。
>>> L = [1, 2, 3] # 共用的列表对象
>>> M = ['X', L, 'Y'] # 嵌入一个到L的引用
>>> M
['X', [1, 2, 3], 'Y']
>>> L[1] = 0 # 也改变了M
>>> M
['X', [1, 0, 3], 'Y']
通常情况下只有在稍大一点的程序里这就显得很重要了,而且这些共用的引用通常确实是你需要的。如果不是的话,你可以明确的给他们创建一个副本来避免共用的引用;对于列表来说,你可以通过使用一个空列表的切片来创建一个顶层的副本:
>>> L = [1, 2, 3]
>>> M = ['X', L[:], 'Y'] # 嵌入一个L的副本
>>> L[1] = 0 # 仅仅改变了L,但是不影响M
>>> L
[1, 0, 3]
>>> M
['X', [1, 2, 3], 'Y']
切片的范围起始从默认的0到被切片的序列的最大长度。如果两者都省略掉了,那么切片会抽取该序列中的所有元素,并创造一个顶层的副本(一个新的,不被公用的对象)。对于字典来说,使用字典的dict.()方法。
静态识别本地域的变量名
Python默认将一个函数中赋值的变量名视作是本地域的,它们存在于该函数的作用域中并且仅仅在函数运行的时候才存在。从技术上讲,Python是在编译def代码时,去静态的识别本地变量,而不是在运行时碰到赋值的时候才识别到的。如果不理解这点的话,会引起人们的误解。比如,看看下面的例子,当你在一个引用之后给一个变量赋值会怎么样:
>>> X = 99
>>> def func():
... print X # 这个时候还不存在
... X = 88 # 在整个def中将X视作本地变量
...
>>> func( ) # 出错了!
你会得到一个“未定义变量名”的错误,但是其原因是很微妙的。当编译这则代码时,Python碰到给X赋值的语句时认为在这个函数中的任何地方X会被视作一个本地变量名。但是之后当真正运行这个函数时,执行print语句的时候,赋值语句还没有发生,这样Python便会报告一个“未定义变量名”的错误。
事实上,之前的这个例子想要做的事情是很模糊的:你是想要先输出那个全局的X,然后创建一个本地的X呢,还是说这是个程序的错误?如果你真的是想要输出这个全局的X,你需要将它在一个全局语句中声明它,或者通过包络模块的名字来引用它。
默认参数和可变对象
在执行def语句时,默认参数的值只被解析并保存一次,而不是每次在调用函数的时候。这通常是你想要的那样,但是因为默认值需要在每次调用时都保持同样对象,你在试图改变可变的默认值(mutable defaults)的时候可要小心了。例如,下面的函数中使用一个空的列表作为默认值,然后在之后每一次函数调用的时候改变它的值:
>>> def saver(x=[]): # 保存一个列表对象
... x.append(1) # 并每次调用的时候
... print x # 改变它的值
...
>>> saver([2]) # 未使用默认值
[2, 1]
>>> saver() # 使用默认值
[1]
>>> saver() # 每次调用都会增加!
[1, 1]
>>> saver()
[1, 1, 1]
有的人将这个视作Python的一个特点——因为可变的默认参数在每次函数调用时保持了它们的状态,它们能提供像C语言中静态本地函数变量的类似的一些功能。但是,当你第一次碰到它时会觉得这很奇怪,并且在Python中有更加简单的办法来在不同的调用之间保存状态(比如说类)。
要摆脱这样的行为,在函数开始的地方用切片或者方法来创建默认参数的副本,或者将默认值的表达式移到函数里面;只要每次函数调用时这些值在函数里,就会每次都得到一个新的对象:
>>> def saver(x=None):
... if x is None: x = [] # 没有传入参数?
... x.append(1) # 改变新的列表
... print x
...
>>> saver([2]) # 没有使用默认值
[2, 1]
>>> saver() # 这次不会变了
[1]
>>> saver()
[1]
其他常见的编程陷阱
下面列举了其他的一些在这里没法详述的陷阱:
在顶层文件中语句的顺序是有讲究的:因为运行或者加载一个文件会从上到下运行它的语句,所以请确保将你未嵌套的函数调用或者类的调用放在函数或者类的定义之后。
reload不影响用from加载的名字:reload最好和import语句一起使用。如果你使用from语句,记得在reload之后重新运行一遍from,否则你仍然使用之前老的名字。
在多重继承中混合的顺序是有讲究的:这是因为对superclass的搜索是从左到右的,在类定义的头部,在多重superclass中如果出现重复的名字,则以最左边的类名为准。
在try语句中空的except子句可能会比你预想的捕捉到更多的错误。在try语句中空的except子句表示捕捉所有的错误,即便是真正的程序错误,和sys.exit()调用,也会被捕捉到。
B. 关于python列表嵌套问题
代码如下:
student = [["001","张三","男"],["002","李四","男"],["003","王五","女"]]
text = input("性别:")
count = 0
for i in student:
if text == i[2]:
count+=1
print("性别{0}共有{1}人".format(text,count))
C. 关于Python 嵌套列表 def popular(graph_list,n) n是一个非负整数
clayton_list = [ [1,2,3], [0,3], [0,4], [0,1], [2] ]
def Calling_popular(graph_list,n):
people = []
result = {}
all = []
for i in graph_list:
for j in i:
people.append(j)
people = set(people)
for z in people:
result[z] = 0
for a in graph_list:
for b in people:
if b in a:
result[b] += 1
for d in people:
if result[d] >= n:
all.append(d)
return all
a = Calling_popular(clayton_list, 2)
print(a)
a = Calling_popular(clayton_list, 3)
print(a)
a = Calling_popular(clayton_list, 0)
print(a)
输出
[0, 1, 2, 3]
[0]
[0, 1, 2, 3, 4]
变量野枝伍没有用心去定义,要是你真的想学应该可以看的颂或懂,可以问搭含我
D. python 读取文件转为嵌套列表,这题应该如何解
file = open('a.txt'碰弊)
txt = file.read()
print txt
txt = txt.splitlines()
print txt
for i in xrange(len(txt)):
print i,txt[i]
txt[i] = txt[i].split(' '腊吵裂轮闭)
print txt[i],'\n'
output = txt
print output
E. 用Python实现合并两个排序的列表,但一直报错,请问怎么修改啊
你所定义的listnodeclass和python自带的listtype是不同的东西,不能通用,必须先转换
其他小错我直接帮你改掉了
下面是改好可以运行的代码:
classListNode(object):
def__init__(self,val):
self.val=val
self.next=None
def__repr__(self):
returnstr(self.val)
defLinkedList(pythonlist):
l=ListNode(pythonlist[0])
c=l
foriinrange(1,len(pythonlist)):
l.next=ListNode(pythonlist[i])
l=l.next
returnc
defPythonList(ListNode):
l=[]
whileListNode!=None:
l.append(ListNode.val)
ListNode=ListNode.next
returnl
classSolution(object):
defmergeTwoLists(self,l1,l2):
ifl1isNone:
returnl2
ifl2isNone:
returnl1
mmyhead=ListNode(0)
mmyhead.next=None
p=mmyhead
:
ifl1.val<l2.val:
p.next=l1
l1=l1.next
else:
p.next=l2
l2=l2.next
p=p.next
ifl1isnotNone:
p.next=l1
else:
p.next=l2
returnmmyhead.next
l1=LinkedList([1,3,5,7])
l2=LinkedList([2,4,6,8])
sol=Solution()
print(PythonList(sol.mergeTwoLists(l1,l2)))
(LinkedList(pythonlist)方法把一个传统的pythonlist转换成你用的首位相衔的listnode形式,PythonList(ListNode)则是转换回来)
同时,linkedlist的数据类型在c里面比较常用,python里面一般用不着这么麻烦
希望对你有帮助
F. Python list 生成式(推导式list comprehension)中嵌套if else
如果按中文习惯写嵌套列表生成式可能写出如下的错误语法
Python的语法是按英文阅读方式设计的,因此,正常的方式应该是
或者用更简洁的形式 [false,true][condition] is the syntax :
通过示例学习Python列表推导
if/else in Python's list comprehension?
python one-line list comprehension: if-else variants
if else in a list comprehension [plicate]
G. 一个python中嵌套列表的问题,下图中的两种写法,结果不一样,这是为什么
题主你好,
我说下我的理解, 这个要从内存分配上去看了.
[0]* 3 得到的结果是: [0,0,0], 这里面3个0是被分配的不同内存地址,而
[[0]] * 3,得到的结果是: [[0],[0],[0]],这里面3个[0]在内存中指的其实是一个地址,你可以将后两个[0]理解为第1个[0]的两个别名.
换个说法: [0]* 3 得到的结果[0,0,0]你将里面的3个0理解为: 张三,李四,王五,这是3个人, 你改其中的一个对另两个人是没有影响的. 而
[[0]]*3 得到的结果[[0],[0],[0]]你可以理解为:张三,小张,阿三,其中小张和阿三是张三的两个小名, 这三个[0]其实是1个人, 所以你改变其中一个[0],另外的两个[0]肯定也会跟着变.
而你直接写[[0],[0],[0]],可以理解为这三个[0]是三个不同的人.
至于为什么[[0]]*3得到的是[[0],[0],[0]], 而直接定义[[0],[0],[0]]看着是一样, 但当修改元素值的时候,得到的结果却不同,这就是python的实现机制了,不用太纠结这个,因为python就是这样设计的,你只需要明白这个逻辑,用的时候会用就好.
写在最后: 这只是我自己的理解, 没有理论依据,希望不会误导题主.
希望可以帮到题主, 欢迎追问.
H. python 按列读取文本数据 列表越界咋回事啊@_@ IndexError:list index out of range
因为空行导致split函数返回的tmp为空,所以tmp[0]导致了数组越界。
分析思答瞎路:
1、报错信息里面已经提示了第12有误。
2、提示为数组index越界,而12行的代码中tmp[0]涉及数组。
3、找到tmp的定义,是split函数分解之后的内容,应当为一个list列表。
4、但是此处连tmp[0]都提示梁举兄有错,说明tmp中没有任何元素。
5、推得for i in f0,中的没一行的数据i有问题,当运行到最后,回出现一个由问题的i。
所以文件最后一行为空行,通常为写入文件函数每行之后附带的 转义字符导致。
IndexError: list index out of range错误的其他情况
第一种情况:
list[index]index超出范围
第二种情况:
list是一个空的,没有一个元素
进行list[0]就会报该错误。
一般外部输入的数据都可能存在问题,所以通常在readlines或者read后要做一次处理。
这样就避免了空橡袭行,字段数不足,以及类型转换出错。
解决方案:
针对第一种情况,通过调试检查代码。
关于第二种情况,有两种方法:
第一种:检查读入的数据是都有问题,比如读入的txt文件是否存在空行等等,第二种解决方案,在代码上改错。
with open("linux_Yue_01.txt","r") as testFile:
testfileList = []
for v testFile.read().split(" ")
if not v.strip(): #字符串去掉空格不为空
continue
testfileList.extend([splitFileNameAndLabel(v)])
注意:[splitFileNameAndLabel(v)]是又方括号的,否则不能成为列表中嵌套列表了。
I. 请教python列表嵌套问题
可以这样写:
l=[{'name':'张三','性别':'男','年龄':12,'成绩':60},{'name':'张三','性别':'女','年龄':12,'成绩':80},{'name':'李四','性别':'男','年龄':13,'成绩':75},{'name':'王五','性别':'男','年龄':12,'成绩':20}]
l=list(filter(lambda d:d['name']=='张三',l))
print(l)
这是运行截图: