编程指南中文版数据结构.docx
《编程指南中文版数据结构.docx》由会员分享,可在线阅读,更多相关《编程指南中文版数据结构.docx(15页珍藏版)》请在冰豆网上搜索。
编程指南中文版数据结构
v26编程指南中文版数据结构
Navigationindexmodules|next|previous|Pythonv2.6.5documentation?
ThePythonTutorial?
5.DataStructures数据结构?
Thischapterdescribessomethingsyou'velearnedaboutalreadyinmoredetail,andaddssomenewthingsaswell.
本章将更加详细的介绍一些你已经了解的东西,另外我们还会添加一些新的东西。
5.1.MoreonListsList的更多细节?
Thelistdatatypehassomemoremethods.Hereareallofthemethodsoflistobjects:
List数据类型还有其他的一些方法。
如下是List的所有方法:
list.append(x)
Addanitemtotheendofthelist;equivalenttoa[len(a):
]=[x].list.extend(L)
Extendthelistbyappendingalltheitemsinthegivenlist;equivalenttoa[len(a):
]=L.list.insert(i,x)
Insertanitematagivenposition.Thefirstargumentistheindexoftheelementbeforewhichtoinsert,soa.insert(0,x)insertsatthefrontofthelist,anda.insert(len(a),x)isequivalenttoa.append(x).list.remove(x)
Removethefirstitemfromthelistwhosevalueisx.Itisanerrorifthereisnosuchitem.list.pop([i])
Removetheitematthegivenpositioninthelist,andreturnit.Ifnoindexisspecified,a.pop()removesandreturnsthelastiteminthelist.(Thesquarebracketsaroundtheiinthemethodsignaturedenotethattheparameterisoptional,notthatyoushouldtypesquarebracketsatthatposition.YouwillseethisnotationfrequentlyinthePythonLibraryReference.)list.index(x)
Returntheindexinthelistofthefirstitemwhosevalueisx.Itisanerrorifthereisnosuchitem.list.count(x)
Returnthenumberoftimesxappearsinthelist.list.sort()
Sorttheitemsofthelist,inplace.list.reverse()
Reversetheelementsofthelist,inplace.Anexamplethatusesmostofthelistmethods:
如下的例子用到了上述的大部分方法:
a=[66.25,333,333,1,1234.5]printa.count(333),a.count(66.25),a.count('x')210a.insert(2,-1)a.append(333)a[66.25,333,-1,333,1,1234.5,333]a.index(333)1a.remove(333)a[66.25,-1,333,1,1234.5,333]a.reverse()a[333,1234.5,1,333,-1,66.25]a.sort()a[-1,1,66.25,333,333,1234.5]
5.1.1.UsingListsasStacks将list作为堆栈使用?
Thelistmethodsmakeitveryeasytousealistasastack,wherethelastelementaddedisthefirstelementretrieved("last-in,first-out").Toaddanitemtothetopofthestack,useappend().Toretrieveanitemfromthetopofthestack,usepop()withoutanexplicitindex.Forexample:
list的方法可以让List很轻易的变成一个堆栈来使用,而堆栈的特点就是最后一个被添加的数字最先被返回("last-in,first-out")。
在堆栈的顶部添加一个元素,使用append()方法,返回堆栈顶部的元素,使用没有显式指定索引的pop()方法:
stack=[3,4,5]stack.append(6)stack.append(7)stack[3,4,5,6,7]stack.pop()7stack[3,4,5,6]stack.pop()6stack.pop()5stack[3,4]
5.1.2.UsingListsasQueues将List当做队列?
Itisalsopossibletousealistasaqueue,wherethefirstelementaddedisthefirstelementretrieved("first-in,first-out");however,listsarenotefficientforthispurpose.Whileappendsandpopsfromtheendoflistarefast,doinginsertsorpopsfromthebeginningofalistisslow(becausealloftheotherelementshavetobeshiftedbyone).
同样也可以将List作为队列使用,队列的特点是最先添加的数据最先返回("first-in,first-out");不过,List对此来说并不高效。
将一个元素从尾部添加或者取出非常快,但是在List的顶部添加或者取出就会变得较慢了(因为其他的元素都将产生移位)。
Toimplementaqueue,usecollections.dequewhichwasdesignedtohavefastappendsandpopsfrombothends.Forexample:
可以用collections.deque去实现一个队列,它恰恰是为了快速从两端添加或者取出数据的。
比如:
fromcollectionsimportdequequeue=deque(["Eric","John","Michael"])queue.append("Terry")#Terryarrivesqueue.append("Graham")#Grahamarrivesqueue.popleft()#Thefirsttoarrivenowleaves'Eric'queue.popleft()#Thesecondtoarrivenowleaves'John'queue#Remainingqueueinorderofarrivaldeque(['Michael','Terry','Graham'])
5.1.3.FunctionalProgrammingTools功能性编程工具?
Therearethreebuilt-infunctionsthatareveryusefulwhenusedwithlists:
filter(),map(),andreduce().
有三个内置的函数在同list一起使用的时候非常有用:
filter(),map(),andreduce()。
filter(function,sequence)returnsasequenceconsistingofthoseitemsfromthesequenceforwhichfunction(item)istrue.Ifsequenceisastringortuple,theresultwillbeofthesametype;otherwise,itisalwaysalist.Forexample,tocomputesomeprimes:
filter(function,sequence)返回序列中function(item)测试为真的所有元素的列表。
如果sequence是一个string或者tuple,会返回和它一样的类型,否则返回一个list。
deff(x):
returnx%2!
=0andx%3!
=0.filter(f,range(2,25))[5,7,11,13,17,19,23]map(function,sequence)callsfunction(item)foreachofthesequence'sitemsandreturnsalistofthereturnvalues.Forexample,tocomputesomecubes:
map(function,sequence)对队列中的每个元素调用function(item)函数,并且返回函数所有返回值的列表。
比如,计算一些立方数:
defcube(x):
returnx*x*x.map(cube,range(1,11))[1,8,27,64,125,216,343,512,729,1000]Morethanonesequencemaybepassed;thefunctionmustthenhaveasmanyargumentsastherearesequencesandiscalledwiththecorrespondingitemfromeachsequence(orNoneifsomesequenceisshorterthananother).Forexample:
可以传入多个队列;不过函数必须也要有和序列数(orNoneifsomesequenceisshorterthananother)一样的形参数,每个队列对应一个形参。
如下:
seq=range(8)defadd(x,y):
returnx+y.map(add,seq,seq)[0,2,4,6,8,10,12,14]reduce(function,sequence)returnsasinglevalueconstructedbycallingthebinaryfunctionfunctiononthefirsttwoitemsofthesequence,thenontheresultandthenextitem,andsoon.Forexample,tocomputethesumofthenumbers1through10:
reduce(function,sequence)返回二参数函数function在元素上的值,其中,函数首先计算前两个元素的值,再将返回值与第三个元素计算,依次计算得到最后结果。
比如,如下例子计算1到10的和:
defadd(x,y):
returnx+y.reduce(add,range(1,11))55Ifthere'sonlyoneiteminthesequence,itsvalueisreturned;ifthesequenceisempty,anexceptionisraised.
如果序列中仅有一个元素,该元素的值被返回;如果序列为空,则会抛出异常。
Athirdargumentcanbepassedtoindicatethestartingvalue.Inthiscasethestartingvalueisreturnedforanemptysequence,andthefunctionisfirstappliedtothestartingvalueandthefirstsequenceitem,thentotheresultandthenextitem,andsoon.Forexample,
也可以传入第三个参数用以表示初始值。
在这种情况下,如果序列为空,则返回该值,部位空的话,则最开始计算该值与第一个元素,然后他们的结果再和第二个数计算,等等。
如下:
defsum(seq):
.defadd(x,y):
returnx+y.returnreduce(add,seq,0).sum(range(1,11))55sum()0Don'tusethisexample'sdefinitionofsum():
sincesummingnumbersissuchacommonneed,abuilt-infunctionsum(sequence)isalreadyprovided,andworksexactlylikethis.
不要使用例子中sum()的定义:
因为求和函数很常用,所以一个内建的sum(sequence)的已经被提供。
Newinversion2.3.5.1.4.ListComprehensions?
Listcomprehensionsprovideaconcisewaytocreatelistswithoutresortingtouseofmap(),filter()and/orlambda.Theresultinglistdefinitiontendsoftentobeclearerthanlistsbuiltusingthoseconstructs.Eachlistcomprehensionconsistsofanexpressionfollowedbyaforclause,thenzeroormorefororifclauses.Theresultwillbealistresultingfromevaluatingtheexpressioninthecontextoftheforandifclauseswhichfollowit.Iftheexpressionwouldevaluatetoatuple,itmustbeparenthesized.
Listcomprehension提供了一种创建List的简便方式,该方式无需使用map(),filter()和/或者lambda。
list采用这种结构的定义通常比List的建立过程要直观得多。
每一个listcomprehension由一个表达式,以及表达式后的一个for从句,然后0个或者多个for或者if从句组成。
如果表达式想要表达为一个tuple,必须用括号括起来。
freshfruit=['banana','loganberry','passionfruit'][weapon.strip()forweaponinfreshfruit]['banana','loganberry','passionfruit']vec=[2,4,6][3*xforxinvec][6,12,18][3*xforxinvecifx3][12,18][3*xforxinvecifx2][[x,x*2]forxinvec][[2,4],[4,16],[6,36]][x,x*2forxinvec]#error-parensrequiredfortuplesFile"stdin",line1,in?
[x,x*2forxinvec]^SyntaxError:
invalidsyntax[(x,x*2)forxinvec][(2,4),(4,16),(6,36)]vec1=[2,4,6]vec2=[4,3,-9][x*yforxinvec1foryinvec2][8,6,-18,16,12,-36,24,18,-54][x+yforxinvec1foryinvec2][6,5,-7,8,7,-5,10,9,-3][vec1[i]*vec2[i]foriinrange(len(vec1))][8,12,-54]Listcomprehensionsaremuchmoreflexiblethanmap()andcanbeappliedtocomplexexpressionsandnestedfunctions:
Listcomprehensions比起map()来说适应性更好,而且可以应用到复杂的表达式和内嵌函数:
[str(round(355/113.0,i))foriinrange(1,6)]['3.1','3.14','3.142','3.1416','3.14159']5.1.5.NestedListComprehensions内嵌ListComprehensions?
Ifyou'vegotthestomachforit,listcomprehensionscanbenested.Theyareapowerfultoolbut–likeallpowerfultools–theyneedtobeusedcarefully,ifatall.
Considerthefollowingexampleofa3x3matrixheldasalistcontainingthreelists,onelistperrow:
如果这很对你的胃口,(我想说)listcomprehension还能够被嵌套。
这是非常强大的工具,不过和许多其他强大工具一样,你也必须小心谨慎的使用。
考虑如下的例子,一个内含3个List的list所表示的3x3的矩阵,每个子list表示一行:
mat=[.[1,2,3],.[4,5,6],.[7,8,9],.]Now,ifyouwantedtoswaprowsandcolumns,youcouldusealistcomprehension:
现在,如果你想交换行和列,你可以使用listcomprehension:
print[[row[i]forrowinmat]foriin[0,1,2]][[1,4,7],[2,5,8],[3,6,9]]Specialcarehastobetakenforthenestedlistcomprehension:
对于内嵌的listcomprehension你需要特别的留意:
Toavoidapprehensionwhennestinglistcomprehensions,readfromrighttoleft.为了消除嵌套listcomprehensions的忧虑,(我们)从右到左阅读。
Amoreverboseversionofthissnippetshowstheflowexplicitly:
下面是一段关于上述代码流程的详细表达:
foriin[0,1,2]:
forrowinmat:
printrow[i],printInrealworld,youshouldpreferbuilt-infunctionstocomplexflowstatements.Thezip()functionwoulddoagreatjobforthisusecase:
在真实世界中,你应该更多的使用内建函数,而不是复杂的流程语句。
zip()函数在这种情况下起了很大的作用:
zip(*mat)[(1,4,7),(2,5,8),(3,6,9)]SeeUnpackingArgumentListsfordetailsontheasteriskinthisline.
参阅UnpackingArgumentLists来获取更多关于本行中星号的细节。
5.2.Thedelstatement?
Thereisawaytoremoveanitemfromalistgivenitsindexinsteadofitsvalue:
thedelstatement.Thisdiffersfromthepop()methodwhichreturnsavalue.Thedelstatementcanalsobeusedtoremoveslicesfromalistorcleartheentirelist(whichwedidearlierbyassignmentofanemptylisttotheslice).Forexample:
这里提供了一种给出索引而不是值对List中元素进行删除的方法:
del语句。
与返回一个值的pop()方法不同。
del语句也可以用于删除List中的一个切片甚至是整个list(早些章节里面我们提到的将一个空List赋值给切片)。
比如:
a=[-1,1,66.25,333,333,1234.5]dela[0]a[1,66.25,333,333,1234.5]dela[2:
4]a[1,66.25,1234.5]dela[:
]adelcanalsobeusedtodeleteentirevariables:
del亦可以用来删除整个变量:
delaReferencingthenameahereafterisanerror(atleastuntilanothervalueisassignedtoit).We'llfindotherusesfordellater.
在此以后(直到它被赋值为另一个值)引用名字a将产生错误。
我们将在后面探索更多del的用法。
5.3.TuplesandSequencesTuples和序列?
Wesawthatlistsandstringshave