問題一:如下的代碼的輸出將是什麼? 說出你的答案並解釋。html
class Parent(object):前端
x = 1java
class Child1(Parent):python
passgit
class Child2(Parent):程序員
passgithub
print Parent.x, Child1.x, Child2.xweb
Child1.x = 2面試
print Parent.x, Child1.x, Child2.x正則表達式
Parent.x = 3
print Parent.x, Child1.x, Child2.x
答案
以上代碼的輸出是:
1 1 1
1 2 1
3 2 3
使你困惑或是驚奇的是關於最後一行的輸出是 3 2 3 而不是 3 2 1。爲何改變了 Parent.x 的值還會改變 Child2.x 的值,可是同時 Child1.x 值卻沒有改變?
這個答案的關鍵是,在 Python 中,類變量在內部是做爲字典處理的。若是一個變量的名字沒有在當前類的字典中發現,將搜索祖先類(好比父類)直到被引用的變量名被找到(若是這個被引用的變量名既沒有在本身所在的類又沒有在祖先類中找到,會引起一個 AttributeError 異常 )。
所以,在父類中設置 x = 1 會使得類變量 X 在引用該類和其任何子類中的值爲 1。這就是由於第一個 print 語句的輸出是 1 1 1。
隨後,若是任何它的子類重寫了該值(例如,咱們執行語句 Child1.x = 2),而後,該值僅僅在子類中被改變。這就是爲何第二個 print 語句的輸出是 1 2 1。
最後,若是該值在父類中被改變(例如,咱們執行語句 Parent.x = 3),這個改變會影響到任何未重寫該值的子類當中的值(在這個示例中被影響的子類是 Child2)。這就是爲何第三個 print 輸出是 3 2 3。
問題二:如下的代碼的輸出將是什麼? 說出你的答案並解釋?
def div1(x,y):
print("%s/%s = %s" % (x, y, x/y))
def div2(x,y):
print("%s//%s = %s" % (x, y, x//y))
div1(5,2)
div1(5.,2)
div2(5,2)
div2(5.,2.)
答案
這個答案實際依賴於你使用的是 Python 2 仍是 Python 3。
在 Python 3 中,指望的輸出是:
5/2 = 2.5
5.0/2 = 2.5
5//2 = 2
5.0//2.0 = 2.0
在 Python 2 中,儘管如此,以上代碼的輸出將是:
5/2 = 2
5.0/2 = 2.5
5//2 = 2
5.0//2.0 = 2.0
默認,若是兩個操做數都是整數,Python 2 自動執行整型計算。結果,5/2 值爲 2,然而 5./2 值爲 ```2.5``。
注意,儘管如此,你能夠在 Python 2 中重載這一行爲(好比達到你想在 Python 3 中的一樣結果),經過添加如下導入:
from __future__ import division
也須要注意的是「雙劃線」(//)操做符將一直執行整除,而無論操做數的類型,這就是爲何 5.0//2.0 值爲 2.0。
注: 在 Python 3 中,/ 操做符是作浮點除法,而 // 是作整除(即商沒有餘數,好比 10 // 3 其結果就爲 3,餘數會被截除掉,而 (-7) // 3 的結果倒是 -3。這個算法與其它不少編程語言不同,須要注意,它們的整除運算會向0的方向取值。而在 Python 2 中,/ 就是整除,即和 Python 3 中的 // 操做符同樣,)
問題三:如下代碼將輸出什麼?
list = ['a', 'b', 'c', 'd', 'e']
print list[10:]
答案
以上代碼將輸出 [],而且不會致使一個 IndexError。
正如人們所指望的,試圖訪問一個超過列表索引值的成員將致使 IndexError(好比訪問以上列表的 list[10])。儘管如此,試圖訪問一個列表的以超出列表成員數做爲開始索引的切片將不會致使 IndexError,而且將僅僅返回一個空列表。
一個討厭的小問題是它會致使出現 bug ,而且這個問題是難以追蹤的,由於它在運行時不會引起錯誤。
問題四:如下的代碼的輸出將是什麼? 說出你的答案並解釋?
def multipliers():
return [lambda x : i * x for i in range(4)]
print [m(2) for m in multipliers()]
你將如何修改 multipliers 的定義來產生指望的結果
答案
以上代碼的輸出是 [6, 6, 6, 6] (而不是 [0, 2, 4, 6])。
這個的緣由是 Python 的閉包的後期綁定致使的 late binding,這意味着在閉包中的變量是在內部函數被調用的時候被查找。因此結果是,當任何 multipliers() 返回的函數被調用,在那時,i 的值是在它被調用時的周圍做用域中查找,到那時,不管哪一個返回的函數被調用,for 循環都已經完成了,i 最後的值是 3,所以,每一個返回的函數 multiplies 的值都是 3。所以一個等於 2 的值被傳遞進以上代碼,它們將返回一個值 6 (好比: 3 x 2)。
(順便說下,正如在 The Hitchhiker’s Guide to Python 中指出的,這裏有一點廣泛的誤解,是關於 lambda 表達式的一些東西。一個 lambda 表達式建立的函數不是特殊的,和使用一個普通的 def 建立的函數展現的表現是同樣的。)
這裏有兩種方法解決這個問題。
最廣泛的解決方案是建立一個閉包,經過使用默認參數當即綁定它的參數。例如:
def multipliers():
return [lambda x, i=i : i * x for i in range(4)]
另一個選擇是,你能夠使用 functools.partial 函數:
from functools import partial
from operator import mul
def multipliers():
return [partial(mul, i) for i in range(4)]
問題五:如下的代碼的輸出將是什麼? 說出你的答案並解釋?
def extendList(val, list=[]):
list.append(val)
return list
list1 = extendList(10)
list2 = extendList(123,[])
list3 = extendList('a')
print "list1 = %s" % list1
print "list2 = %s" % list2
print "list3 = %s" % list3
你將如何修改 extendList 的定義來產生指望的結果
以上代碼的輸出爲:
list1 = [10, 'a']
list2 = [123]
list3 = [10, 'a']
許多人會錯誤的認爲 list1 應該等於 [10] 以及 list3 應該等於 ['a']。認爲 list 的參數會在 extendList 每次被調用的時候會被設置成它的默認值 []。
儘管如此,實際發生的事情是,新的默認列表僅僅只在函數被定義時建立一次。隨後當 extendList 沒有被指定的列表參數調用的時候,其使用的是同一個列表。這就是爲何當函數被定義的時候,表達式是用默認參數被計算,而不是它被調用的時候。
所以,list1 和 list3 是操做的相同的列表。而 ````list2是操做的它建立的獨立的列表(經過傳遞它本身的空列表做爲list``` 參數的值)。
extendList 函數的定義能夠作以下修改,但,當沒有新的 list 參數被指定的時候,會老是開始一個新列表,這更加多是一直指望的行爲。
def extendList(val, list=None):
if list is None:
list = []
list.append(val)
return list
使用這個改進的實現,輸出將是:
list1 = [10]
list2 = [123]
list3 = ['a']
最近,整理了一些Python常見的面試題目,語言是一種工具,可是多角度的瞭解工具能幫助咱們更好的工做。
從不少國內網站以及一些國外論壇翻譯過來的,雖然本文標註爲"原創",可是僅僅是本身平常整理的材料,文章後面會附上參考來源。
第一部分:
簡易/中等
什麼是Python裝飾器,如何使用?
你會如何設置不少項目,其中每個使用Python的不一樣版本和第三方庫?
什麼是PEP8和你是如何遵循它的規範?
參數是如何傳遞的 - 傳值仍是傳引用? (容易,但又不那麼容易,不肯定是否能清楚地回答這個問題)
什麼是列表解析、字典解析?舉個例子
請用三種不一樣的方法完成"提取列表中每三個項目"?
你知道列表和元組之間的區別麼?舉個例子?
你知道range和xrange之間的區別? 針對python2.x版本
談談Python2.x和3.x之間的一些區別?
with語句及其用法?
如何避免對模塊或方法的重複import?
爲何GIL重要?
什麼是「特殊方法"(如<foo>)?它們如何工做的?
python中什麼是一級對象(first-class objects)? 如何將函數做爲一級對象操縱呢?
"class Foo" 和 "class Foo(object)"之間的區別?
棘手的
Python中,如何讀取大小爲8GB的文件? (即python如何讀取大文件)
你爲什麼喜歡Python,又有哪些不喜歡的部分?
不能借助內置方法如string.atoi或者int(),可否將ASCII字符轉換爲整數?
主觀的
你用製表符仍是空格,哪些是更好?
其餘:(不斷擴充.......本身整理......)
列表與元組的區別是什麼.分別在什麼狀況下使用?
談談你用過的Python庫?
對Python中裝飾器的認識?
Python中文件/模塊/包之間的關係?包文件夾下__init__.py做用是什麼?
Python是如何進行內存管理的?
第二部分:基本數據結構
第三部分:
下面的題目看看便可。。。
1:Python如何實現單例模式? 請參考:http://blog.csdn.Net/ghostfromheaven/article/details/7671853
2:什麼是lambda函數?
Python容許你定義一種單行的小函數。定義lambda函數的形式以下:labmda 參數:表達式lambda函數默認返回表達式的值。你也能夠將其賦值給一個變量。lambda函數能夠接受任意個參數,包括可選參數,可是表達式只有一個:
>>> g = lambda x, y: x*y
>>> g(3,4)
12
>>> g = lambda x, y=0, z=0: x+y+z
>>> g(1)
1
>>> g(3, 4, 7)
14
也可以直接使用lambda函數,不把它賦值給變量:
>>> (lambda x,y=0,z=0:x+y+z)(3,5,6)
14
若是你的函數很是簡單,只有一個表達式,不包含命令,能夠考慮lambda函數。不然,你仍是定義函數纔對,畢竟函數沒有這麼多限制。
3:Python是如何進行類型轉換的?
Python提供了將變量或值從一種類型轉換成另外一種類型的內置函數。int函數可以將符合數學格式數字型字符串轉換成整數。不然,返回錯誤信息。
>>> int(」34″)
34
>>> int(」1234ab」) #不能轉換成整數
ValueError: invalid literal for int(): 1234ab
函數int也可以把浮點數轉換成整數,但浮點數的小數部分被截去。
>>> int(34.1234)
34
>>> int(-2.46)
-2
函數°oat將整數和字符串轉換成浮點數:
>>> float(」12″)
12.0
>>> float(」1.111111″)
1.111111
函數str將數字轉換成字符:
>>> str(98)
‘98′
>>> str(」76.765″)
‘76.765′
整數1和浮點數1.0在python中是不一樣的。雖然它們的值相等的,但卻屬於不一樣的類型。這兩個數在計算機的存儲形式也是不同。
4:Python如何定義一個函數
函數的定義形式如
下:
def <name>(arg1, arg2,… argN):
< statements>
函數的名字也必須以字母開頭,能夠包括下劃線「 」,但不能把Python的
關鍵字定義成函數的名字。函數內的語句數量是任意的,每一個語句至少有
一個空格的縮進,以表示此語句屬於這個函數的。縮進結束的地方,函數
天然結束。
下面定義了一個兩個數相加的函數:
>>> def add(p1, p2):
print p1, 「+」, p2, 「=」, p1+p2
>>> add(1, 2)
1 + 2 = 3
函數的目的是把一些複雜的操做隱藏,來簡化程序的結構,使其容易
閱讀。函數在調用前,必須先定義。也能夠在一個函數內部定義函數,內
部函數只有在外部函數調用時纔可以被執行。程序調用函數時,轉到函數
內部執行函數內部的語句,函數執行完畢後,返回到它離開程序的地方,
執行程序的下一條語句。
5:Python是如何進行內存管理的?
Python的內存管理是由Python得解釋器負責的,開發人員能夠從內存管理事務中解放出來,致力於應用程序的開發,這樣就使得開發的程序錯誤更少,程序更健壯,開發週期更短
6:如何反序的迭代一個序列?how do I iterate over a sequence in reverse order
若是是一個list, 最快的解決方案是:
list.reverse()
try:
for x in list:
「do something with x」
finally:
list.reverse()
若是不是list, 最通用可是稍慢的解決方案是:
for i in range(len(sequence)-1, -1, -1):
x = sequence[i]
< do something with x>
7:Python裏面如何實現tuple和list的轉換?
函數tuple(seq)能夠把全部可迭代的(iterable)序列轉換成一個tuple, 元素不變,排序也不變。
例如,tuple([1,2,3])返回(1,2,3), tuple(’abc’)返回(’a’.’b',’c').若是參數已是一個tuple的話,函數不作任何拷貝而直接返回原來的對象,因此在不肯定對象是否是tuple的時候來調用tuple()函數也不是很耗費的。
函數list(seq)能夠把全部的序列和可迭代的對象轉換成一個list,元素不變,排序也不變。
例如 list([1,2,3])返回(1,2,3), list(’abc’)返回['a', 'b', 'c']。若是參數是一個list, 她會像set[:]同樣作一個拷貝
8:Python面試題:請寫出一段Python代碼實現刪除一個list裏面的重複元素
能夠先把list從新排序,而後從list的最後開始掃描,代碼以下:
if List:
List.sort()
last = List[-1]
for i in range(len(List)-2, -1, -1):
if last==List[i]: del List[i]
else: last=List[i]
9:Python文件操做的面試題
1. 如何用Python刪除一個文件?
使用os.remove(filename)或者os.unlink(filename);
2. Python如何copy一個文件?
shutil模塊有一個copyfile函數能夠實現文件拷貝
10:Python裏面如何生成隨機數?
標準庫random實現了一個隨機數生成器,實例代碼以下:
import random
random.random()
它會返回一個隨機的0和1之間的浮點數
11:如何用Python來發送郵件?
能夠使用smtplib標準庫。
如下代碼能夠在支持SMTP監聽器的服務器上執行。
import sys, smtplib
fromaddr = raw_input(」From: 「)
toaddrs = raw_input(」To: 「).split(’,')
print 「Enter message, end with ^D:」
msg = 」
while 1:
line = sys.stdin.readline()
if not line:
break
msg = msg + line
# 發送郵件部分
server = smtplib.SMTP(’localhost’)
server.sendmail(fromaddr, toaddrs, msg)
server.quit()
12:Python裏面如何拷貝一個對象?
通常來講能夠使用copy.copy()方法或者copy.deepcopy()方法,幾乎全部的對象均可以被拷貝
一些對象能夠更容易的拷貝,Dictionaries有一個copy方法:
newdict = olddict.copy()
13:有沒有一個工具能夠幫助查找python的bug和進行靜態的代碼分析?
有,PyChecker是一個python代碼的靜態分析工具,它能夠幫助查找python代碼的bug, 會對代碼的複雜度和格式提出警告
Pylint是另一個工具能夠進行coding standard檢查。
14:如何在一個function裏面設置一個全局的變量?
解決方法是在function的開始插入一個global聲明:
def f()
global x
14:有兩個序列a,b,大小都爲n,序列元素的值任意整形數,無序;要求:經過交換a,b中的元素,使[序列a元素的和]與[序列b元素的和]之間的差最小。
1. 將兩序列合併爲一個序列,並排序,爲序列Source
2. 拿出最大元素Big,次大的元素Small
3. 在餘下的序列S[:-2]進行平分,獲得序列max,min
4. 將Small加到max序列,將Big加大min序列,從新計算新序列和,和大的爲max,小的爲min。
Python代碼
def mean( sorted_list ):
if not sorted_list:
return (([],[]))
big = sorted_list[-1]
small = sorted_list[-2]
big_list, small_list = mean(sorted_list[:-2])
big_list.append(small)
small_list.append(big)
big_list_sum = sum(big_list)
small_list_sum = sum(small_list)
if big_list_sum > small_list_sum:
return ( (big_list, small_list))
else:
return (( small_list, big_list))
tests = [ [1,2,3,4,5,6,700,800],
[10001,10000,100,90,50,1],
range(1, 11),
[12312, 12311, 232, 210, 30, 29, 3, 2, 1, 1]
]
for l in tests:
l.sort()
print 「Source List:\t」, l
l1,l2 = mean(l)
print 「Result List:\t」, l1, l2
print 「Distance:\t」, abs(sum(l1)-sum(l2))
print ‘-*’*40
輸出結果
Python代碼
Source List: [1, 2, 3, 4, 5, 6, 700, 800]
Result List: [1, 4, 5, 800] [2, 3, 6, 700]
Distance: 99
-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
Source List: [1, 50, 90, 100, 10000, 10001]
Result List: [50, 90, 10000] [1, 100, 10001]
Distance: 38
-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
Source List: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
Result List: [2, 3, 6, 7, 10] [1, 4, 5, 8, 9]
Distance: 1
-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
Source List: [1, 1, 2, 3, 29, 30, 210, 232, 12311, 12312]
Result List: [1, 3, 29, 232, 12311] [1, 2, 30, 210, 12312]
Distance: 21
-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
15:用Python匹配HTML tag的時候,<.*>和<.*?>有什麼區別?
當重複匹配一個正則表達式時候, 例如<.*>, 當程序執行匹配的時候,會返回最大的匹配值
例如:
import re
s = ‘<html><head><title>Title</title>’
print(re.match(’<.*>’, s).group())
會返回一個匹配<html><head><title>Title</title>而不是<html>
而
import re
s = ‘<html><head><title>Title</title>’
print(re.match(’<.*?>’, s).group())
則會返回<html>
<.*>這種匹配稱做貪心匹配 <.*?>稱做非貪心匹配
16:Python裏面search()和match()的區別?
match()函數只檢測RE是否是在string的開始位置匹配, search()會掃描整個string查找匹配, 也就是說match()只有在0位置匹配成功的話纔有返回,若是不是開始位置匹配成功的話,match()就返回none
例如:
print(re.match(’super’, ’superstition’).span())會返回(0, 5)
而print(re.match(’super’, ‘insuperable’))則返回None
search()會掃描整個字符串並返回第一個成功的匹配
例如:print(re.search(’super’, ’superstition’).span())返回(0, 5)
print(re.search(’super’, ‘insuperable’).span())返回(2, 7)
17:如何用Python來進行查詢和替換一個文本字符串?
能夠使用sub()方法來進行查詢和替換,sub方法的格式爲:sub(replacement, string[, count=0])
replacement是被替換成的文本
string是須要被替換的文本
count是一個可選參數,指最大被替換的數量
例子:
import re
p = re.compile(’(blue|white|red)’)
print(p.sub(’colour’,'blue socks and red shoes’))
print(p.sub(’colour’,'blue socks and red shoes’, count=1))
輸出:
colour socks and colour shoes
colour socks and red shoes
subn()方法執行的效果跟sub()同樣,不過它會返回一個二維數組,包括替換後的新的字符串和總共替換的數量
例如:
import re
p = re.compile(’(blue|white|red)’)
print(p.subn(’colour’,'blue socks and red shoes’))
print(p.subn(’colour’,'blue socks and red shoes’, count=1))
輸出
(’colour socks and colour shoes’, 2)
(’colour socks and red shoes’, 1)
18:介紹一下except的用法和做用?
Python的except用來捕獲全部異常, 由於Python裏面的每次錯誤都會拋出 一個異常,因此每一個程序的錯誤都被看成一個運行時錯誤。
一下是使用except的一個例子:
try:
foo = opne(」file」) #open被錯寫爲opne
except:
sys.exit(」could not open file!」)
由於這個錯誤是因爲open被拼寫成opne而形成的,而後被except捕獲,因此debug程序的時候很容易不知道出了什麼問題
下面這個例子更好點:
try:
foo = opne(」file」) # 這時候except只捕獲IOError
except IOError:
sys.exit(」could not open file」)
19:Python中pass語句的做用是什麼?
pass語句什麼也不作,通常做爲佔位符或者建立佔位程序,pass語句不會執行任何操做,好比:
while False:
pass
pass一般用來建立一個最簡單的類:
class MyEmptyClass:
pass
pass在軟件設計階段也常常用來做爲TODO,提醒實現相應的實現,好比:
def initlog(*args):
pass #please implement this
20:介紹一下Python下range()函數的用法?
若是須要迭代一個數字序列的話,能夠使用range()函數,range()函數能夠生成等差級數。
如例:
for i in range(5)
print(i)
這段代碼將輸出0, 1, 2, 3, 4五個數字
range(10)會產生10個值, 也可讓range()從另一個數字開始,或者定義一個不一樣的增量,甚至是負數增量
range(5, 10)從5到9的五個數字
range(0, 10, 3) 增量爲三, 包括0,3,6,9四個數字
range(-10, -100, -30) 增量爲-30, 包括-10, -40, -70
能夠一塊兒使用range()和len()來迭代一個索引序列
例如:
a = ['Nina', 'Jim', 'Rainman', 'Hello']
for i in range(len(a)):
print(i, a[i])
1. 如何用Python刪除一個文件?
使用os.remove(filename)或者os.unlink(filename);
2. Python如何copy一個文件?
shutil模塊有一個copyfile函數能夠實現文件拷貝
1. 如何用Python刪除一個文件?
使用os.remove(filename)或者os.unlink(filename);
2. Python如何copy一個文件?
shutil模塊有一個copyfile函數能夠實現文件拷貝
3. python程序中文輸出問題怎麼解決?
方法一:
用encode和decode
如:
import os.path
import xlrd,sys
Filename=’/home/tom/Desktop/1234.xls’
if not os.path.isfile(Filename):
raise NameError,」%s is not a valid filename」%Filename
bk=xlrd.open_workbook(Filename)
shxrange=range(bk.nsheets)
print shxrange
for x in shxrange:
p=bk.sheets()[x].name.encode(‘utf-8′)
print p.decode(‘utf-8′)方法二:
在文件開頭加上
reload(sys)
sys.setdefaultencoding(‘utf8′)這2行,再試着運行一下
Python裏面如何實現tuple和list的轉換?
函數tuple(seq)能夠把全部可迭代的(iterable)序列轉換成一個tuple, 元素不變,排序也不變。例如,tuple([1,2,3])返回(1,2,3), tuple(‘abc’)返回(‘a’.'b’,'c’).若是參數已是一個tuple的話,函數不作任何拷貝而直接返回原來的對象,因此在不肯定對象是否是tuple的時候來調用tuple()函數也不是很耗費的。函數list(seq)能夠把全部的序列和可迭代的對象轉換成一個list,元素不變,排序也不變。例如 list([1,2,3])返回(1,2,3), list(‘abc’)返回['a', 'b', 'c']。若是參數是一個list, 她會像set[:]同樣作一個拷貝
如何反序的迭代一個序列?how do I iterate over a sequence in reverse order
若是是一個list, 最快的解決方案是:
list.reverse()
try:
for x in list:
「do something with x」
finally:
list.reverse()
若是不是list, 最通用可是稍慢的解決方案是:
for i in range(len(sequence)-1, -1, -1):
x = sequence[i]
Python是如何進行類型轉換的?
Python提供了將變量或值從一種類型轉換成另外一種類型的內置函數。int函數可以將符合數學格式數字型字符串轉換成整數。不然,返回錯誤信息。
>>> int(「34″)
34
>>> int(「1234ab」) #不能轉換成整數
ValueError: invalid literal for int(): 1234ab
函數int也可以把浮點數轉換成整數,但浮點數的小數部分被截去。
>>> int(34.1234)
34
>>> int(-2.46)
-2
函數°oat將整數和字符串轉換成浮點數:
>>> float(「12″)
12.0
>>> float(「1.111111″)
1.111111
函數str將數字轉換成字符:
>>> str(98)
’98′
>>> str(「76.765″)
’76.765′
整數1和浮點數1.0在python中是不一樣的。雖然它們的值相等的,但卻屬於不一樣的類型。這兩個數在計算機的存儲形式也是不同。
用Python匹配HTML tag的時候,<.*>和<.*?>有什麼區別?
當重複匹配一個正則表達式時候, 例如, 當程序執行匹配的時候,會返回最大的匹配值
例如:
import re
s = ‘Title’
print(re.match(‘’, s).group())會返回一個匹配Title而不是、
import re
s = ‘Title’
print(re.match(‘’, s).group())則會返回這種匹配稱做貪心匹配 稱做非貪心匹配
Python的兩道面試題
有沒有一個工具能夠幫助查找python的bug和進行靜態的代碼分析?有,PyChecker是一個python代碼的靜態分析工具,它能夠幫助查找python代碼的bug, 會對代碼的複雜度和格式提出警告
Pylint是另一個工具能夠進行coding standard檢查。
2. 如何在一個function裏面設置一個全局的變量?解決方法是在function的開始插入一個global聲明:
def f()
global x
請用Python寫一個獲取用戶輸入數字,並根據數字大小輸出不一樣信息的腳本
代碼以下(Python 3.0 下調試經過)
x = int(input(「Please enter an integer:」))
if x < 0:
x = 0
print (‘Negative changed to zero’)
elif x == 0:
print (‘Zero’)
elif x == 1:
print (‘Single’)
else:
print (‘More’)
Python面試題:Python裏面如何生成隨機數?
標準庫random實現了一個隨機數生成器,實例代碼以下:
import random
random.random()
它會返回一個隨機的0和1之間的浮點數
華爲python面試題
有兩個序列a,b,大小都爲n,序列元素的值任意整形數,無序;
要求:經過交換a,b中的元素,使[序列a元素的和]與[序列b元素的和]之間的差最小。
有兩個序列a,b,大小都爲n,序列元素的值任意整形數,無序;
要求:經過交換a,b中的元素,使[序列a元素的和]與[序列b元素的和]之間的差最小。
1. 將兩序列合併爲一個序列,並排序,爲序列Source
2. 拿出最大元素Big,次大的元素Small
3. 在餘下的序列S[:-2]進行平分,獲得序列max,min
4. 將Small加到max序列,將Big加大min序列,從新計算新序列和,和大的爲max,小的爲min。
Python代碼
def mean( sorted_list ):
if not sorted_list:
return (([],[]))
big = sorted_list[-1]
small = sorted_list[-2]
big_list, small_list = mean(sorted_list[:-2])
big_list.append(small)
small_list.append(big)
big_list_sum = sum(big_list)
small_list_sum = sum(small_list)
if big_list_sum > small_list_sum:
return ( (big_list, small_list))
else:
return (( small_list, big_list))
tests = [ [1,2,3,4,5,6,700,800],
[10001,10000,100,90,50,1],
range(1, 11),
[12312, 12311, 232, 210, 30, 29, 3, 2, 1, 1]]
for l in tests:
l.sort()
print
print 「Source List:\t」, l
l1,l2 = mean(l)
print 「Result List:\t」, l1, l2
print 「Distance:\t」, abs(sum(l1)-sum(l2))
print ‘-*’*40輸出結果
Python代碼
Source List: [1, 2, 3, 4, 5, 6, 700, 800]
Result List: [1, 4, 5, 800] [2, 3, 6, 700]
Distance: 99
-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
Source List: [1, 50, 90, 100, 10000, 10001]
Result List: [50, 90, 10000] [1, 100, 10001]
Distance: 38
-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
Source List: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
Result List: [2, 3, 6, 7, 10] [1, 4, 5, 8, 9]
Distance: 1
-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
Source List: [1, 1, 2, 3, 29, 30, 210, 232, 12311, 12312]
Result List: [1, 3, 29, 232, 12311] [1, 2, 30, 210, 12312]
Distance: 21
-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
1 Python的函數參數傳遞
看兩個例子:
a = 1
def fun(a):
a = 2
fun(a)
print a # 1
a = []
def fun(a):
a.append(1)
fun(a)
print a # [1]
全部的變量均可以理解是內存中一個對象的「引用」,或者,也能夠看似c中void*的感受。
這裏記住的是類型是屬於對象的,而不是變量。而對象有兩種,「可更改」(mutable)與「不可更改」(immutable)對象。在python中,strings, tuples, 和numbers是不可更改的對象,而list,dict等則是能夠修改的對象。(這就是這個問題的重點)
當一個引用傳遞給函數的時候,函數自動複製一份引用,這個函數裏的引用和外邊的引用沒有半毛關係了.因此第一個例子裏函數把引用指向了一個不可變對象,當函數返回的時候,外面的引用沒半毛感受.而第二個例子就不同了,函數內的引用指向的是可變對象,對它的操做就和定位了指針地址同樣,在內存裏進行修改.
若是還不明白的話,這裏有更好的解釋: http://stackoverflow.com/questions/986006/how-do-i-pass-a-variable-by-reference14
2 Python中的元類(metaclass)
這個很是的不經常使用,可是像ORM這種複雜的結構仍是會須要的,詳情請看:http://stackoverflow.com/questions/100003/what-is-a-metaclass-in-python
3 @staticmethod和@classmethod
Python其實有3個方法,即靜態方法(staticmethod),類方法(classmethod)和實例方法,以下:
def foo(x):
print "executing foo(%s)"%(x)
class A(object):
def foo(self,x):
print "executing foo(%s,%s)"%(self,x)
@classmethod
def class_foo(cls,x):
print "executing class_foo(%s,%s)"%(cls,x)
@staticmethod
def static_foo(x):
print "executing static_foo(%s)"%x
a=A()
這裏先理解下函數參數裏面的self和cls.這個self和cls是對類或者實例的綁定,對於通常的函數來講咱們能夠這麼調用foo(x),這個函數就是最經常使用的,它的工做跟任何東西(類,實例)無關.對於實例方法,咱們知道在類裏每次定義方法的時候都須要綁定這個實例,就是foo(self, x),爲何要這麼作呢?由於實例方法的調用離不開實例,咱們須要把實例本身傳給函數,調用的時候是這樣的a.foo(x)(實際上是foo(a, x)).類方法同樣,只不過它傳遞的是類而不是實例,A.class_foo(x).注意這裏的self和cls能夠替換別的參數,可是python的約定是這倆,仍是不要改的好.
對於靜態方法其實和普通的方法同樣,不須要對誰進行綁定,惟一的區別是調用的時候須要使用a.static_foo(x)或者A.static_foo(x)來調用.
|\|實例方法|類方法|靜態方法|
|:--|:--|:--|:--|
|a = A()|a.foo(x)|a.class_foo(x)|a.static_foo(x)|
|A|不可用|A.class_foo(x)|A.static_foo(x)|
4 類變量和實例變量
class Person:
name="aaa"
p1=Person()
p2=Person()
p1.name="bbb"
print p1.name # bbb
print p2.name # aaa
print Person.name # aaa
類變量就是供類使用的變量,實例變量就是供實例使用的.
這裏p1.name="bbb"是實例調用了類變量,這其實和上面第一個問題同樣,就是函數傳參的問題,p1.name一開始是指向的類變量name="aaa",可是在實例的做用域裏把類變量的引用改變了,就變成了一個實例變量,self.name再也不引用Person的類變量name了.
能夠看看下面的例子:
class Person:
name=[]
p1=Person()
p2=Person()
p1.name.append(1)
print p1.name # [1]
print p2.name # [1]
print Person.name # [1]
參考:http://stackoverflow.com/questions/6470428/catch-multiple-exceptions-in-one-line-except-block
5 Python自省
這個也是python彪悍的特性.
自省就是面向對象的語言所寫的程序在運行時,所能知道對象的類型.簡單一句就是運行時可以得到對象的類型.好比type(),dir(),getattr(),hasattr(),isinstance().
6 字典推導式
可能你見過列表推導時,卻沒有見過字典推導式,在2.7中才加入的:
d = {key: value for (key, value) in iterable}
7 Python中單下劃線和雙下劃線
>>> class MyClass():
... def __init__(self):
... self.__superprivate = "Hello"
... self._semiprivate = ", world!"
...
>>> mc = MyClass()
>>> print mc.__superprivate
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: myClass instance has no attribute '__superprivate'
>>> print mc._semiprivate
, world!
>>> print mc.__dict__
{'_MyClass__superprivate': 'Hello', '_semiprivate': ', world!'}
__foo__:一種約定,Python內部的名字,用來區別其餘用戶自定義的命名,以防衝突.
_foo:一種約定,用來指定變量私有.程序員用來指定私有變量的一種方式.
__foo:這個有真正的意義:解析器用_classname__foo來代替這個名字,以區別和其餘類相同的命名.
詳情見:http://stackoverflow.com/questions/1301346/the-meaning-of-a-single-and-a-double-underscore-before-an-object-name-in-python
或者: http://www.zhihu.com/question/197549413
8 字符串格式化:%和.format
.format在許多方面看起來更便利.對於%最煩人的是它沒法同時傳遞一個變量和元組.你可能會想下面的代碼不會有什麼問題:
"hi there %s" % name
可是,若是name剛好是(1,2,3),它將會拋出一個TypeError異常.爲了保證它老是正確的,你必須這樣作:
"hi there %s" % (name,) # 提供一個單元素的數組而不是一個參數
可是有點醜..format就沒有這些問題.你給的第二個問題也是這樣,.format好看多了.
你爲何不用它?
不知道它(在讀這個以前)
爲了和Python2.5兼容(譬如logging庫建議使用%(issue #4))
Python string formatting: % vs. .format
asked by NorthIsUp on 06:46PM - 22 Feb 11
python, performance, logging, string-formatting
9 迭代器和生成器
最近打算用Python作分詞,在生成字典的時候,我採用的方法是逐個元素處理的方法,結果因爲訓練語料中的數據量過大,這樣處理很慢。因此打算學學迭代器與生成器,看看能不能對序列進行批量處理(這點和matlab有點像)如下內容轉載自:http://blog.csdn.net/chszs/archive/2009/01/24/3852669.aspx 把美文本身索羅到博客中來,個人博客就能夠成爲一個小的資料庫了
Python的迭代器和生成器
Iterator是迭代器的意思,它的做用是一次產生一個數據項,直到沒有爲止。這樣在 for 循環中就能夠對它進行循環處理了。那麼它與通常的序列類型(list, tuple等)有什麼區別呢?它一次只返回一個數據項,佔用更少的內存。但它須要記住當前的狀態,以便返回下一數據項。它是一個有着next()方法的對象。而序列類型則保存了全部的數據項,它們的訪問是經過索引進行的。
1、迭代器Iterators
迭代器僅是一容器對象,它實現了迭代器協議。它有兩個基本方法:
1)next方法
返回容器的下一個元素
2)__iter__方法
返回迭代器自身
迭代器可以使用內建的iter方法建立,見例子:
>>> i = iter('abc')
>>> i.next()
'a'
>>> i.next()
'b'
>>> i.next()
'c'
>>> i.next()
Traceback (most recent call last):
File "<string>", line 1, in <string>
StopIteration:
class MyIterator(object):
def __init__(self, step):
self.step = step
def next(self):
"""Returns the next element."""
if self.step==0:
raise StopIteration
self.step-=1
return self.step
def __iter__(self):
"""Returns the iterator itself."""
return self
for el in MyIterator(4):
print el
--------------------
結果:
3
2
1
0
2、生成器Generators
從Python2.2起,生成器提供了一種簡潔的方式幫助返回列表元素的函數來完成簡單和有效的代碼。
它基於yield指令,容許中止函數並當即返回結果。
此函數保存其執行上下文,若是須要,可當即繼續執行。
例如Fibonacci函數:
def fibonacci():
a,b=0,1
while True:
yield b
a,b = b, a+b
fib=fibonacci()
print fib.next()
print fib.next()
print fib.next()
print [fib.next() for i in range(10)]
--------------------
結果:
1
1
2
[3, 5, 8, 13, 21, 34, 55, 89, 144, 233]
PEP Python Enhancement Proposal Python加強建議
tokenize模塊
>>> import tokenize
>>> reader = open('c:/temp/py1.py').next
>>> tokens=tokenize.generate_tokens(reader)
>>> tokens.next()
(1, 'class', (1, 0), (1, 5), 'class MyIterator(object):\n')
>>> tokens.next()
(1, 'MyIterator', (1, 6), (1, 16), 'class MyIterator(object):\n')
>>> tokens.next()
(51, '(', (1, 16), (1, 17), 'class MyIterator(object):\n')
例子:
def power(values):
for value in values:
print 'powering %s' %value
yield value
def adder(values):
for value in values:
print 'adding to %s' %value
if value%2==0:
yield value+3
else:
yield value+2
elements = [1,4,7,9,12,19]
res = adder(power(elements))
print res.next()
print res.next()
--------------------
結果:
powering 1
adding to 1
3
powering 4
adding to 4
7
保持代碼簡單,而不是數據。
注意:寧肯有大量簡單的可迭代函數,也不要一個複雜的一次只計算出一個值的函數。
例子:
def psychologist():
print 'Please tell me your problems'
while True:
answer = (yield)
if answer is not None:
if answer.endswith('?'):
print ("Don't ask yourself too much questions")
elif 'good' in answer:
print "A that's good, go on"
elif 'bad' in answer:
print "Don't be so negative"
free = psychologist()
print free.next()
print free.send('I feel bad')
print free.send("Why I shouldn't ?")
print free.send("ok then i should find what is good for me")
--------------------
結果:
Please tell me your problems
None
Don't be so negative
None
Don't ask yourself too much questions
None
A that's good, go on
None
10 *args and **kwargs
用*args和**kwargs只是爲了方便並無強制使用它們.
當你不肯定你的函數裏將要傳遞多少參數時你能夠用*args.例如,它能夠傳遞任意數量的參數:
>>> def print_everything(*args):
for count, thing in enumerate(args):
... print '{0}. {1}'.format(count, thing)
...
>>> print_everything('apple', 'banana', 'cabbage')
0. apple
1. banana
2. cabbage
類似的,**kwargs容許你使用沒有事先定義的參數名:
>>> def table_things(**kwargs):
... for name, value in kwargs.items():
... print '{0} = {1}'.format(name, value)
...
>>> table_things(apple = 'fruit', cabbage = 'vegetable')
cabbage = vegetable
apple = fruit
你也能夠混着用.命名參數首先得到參數值而後全部的其餘參數都傳遞給*args和**kwargs.命名參數在列表的最前端.例如:
def table_things(titlestring, **kwargs)
*args和**kwargs能夠同時在函數的定義中,可是*args必須在**kwargs前面.
當調用函數時你也能夠用*和**語法.例如:
>>> def print_three_things(a, b, c):
... print 'a = {0}, b = {1}, c = {2}'.format(a,b,c)
...
>>> mylist = ['aardvark', 'baboon', 'cat']
>>> print_three_things(*mylist)
a = aardvark, b = baboon, c = cat
就像你看到的同樣,它能夠傳遞列表(或者元組)的每一項並把它們解包.注意必須與它們在函數裏的參數相吻合.固然,你也能夠在函數定義或者函數調用時用*.
asked by MacPython on 08:28AM - 03 Aug 10
python, args, kwargs
11 面向切面編程AOP和裝飾器
這個AOP一聽起來有點懵,同窗面阿里的時候就被問懵了...
裝飾器是一個很著名的設計模式,常常被用於有切面需求的場景,較爲經典的有插入日誌、性能測試、事務處理等。裝飾器是解決這類問題的絕佳設計,有了裝飾器,咱們就能夠抽離出大量函數中與函數功能自己無關的雷同代碼並繼續重用。歸納的講,裝飾器的做用就是爲已經存在的對象添加額外的功能。
12 鴨子類型
「當看到一隻鳥走起來像鴨子、游泳起來像鴨子、叫起來也像鴨子,那麼這隻鳥就能夠被稱爲鴨子。」
咱們並不關心對象是什麼類型,究竟是不是鴨子,只關心行爲。
好比在python中,有不少file-like的東西,好比StringIO,GzipFile,socket。它們有不少相同的方法,咱們把它們看成文件使用。
又好比list.extend()方法中,咱們並不關心它的參數是否是list,只要它是可迭代的,因此它的參數能夠是list/tuple/dict/字符串/生成器等.
鴨子類型在動態語言中常用,很是靈活,使得python不想java那樣專門去弄一大堆的設計模式。
13 Python中重載
函數重載主要是爲了解決兩個問題。
可變參數類型。
可變參數個數。
另外,一個基本的設計原則是,僅僅當兩個函數除了參數類型和參數個數不一樣之外,其功能是徹底相同的,此時才使用函數重載,若是兩個函數的功能其實不一樣,那麼不該當使用重載,而應當使用一個名字不一樣的函數。
好吧,那麼對於狀況 1 ,函數功能相同,可是參數類型不一樣,python 如何處理?答案是根本不須要處理,由於 python 能夠接受任何類型的參數,若是函數的功能相同,那麼不一樣的參數類型在 python 中極可能是相同的代碼,沒有必要作成兩個不一樣函數。
那麼對於狀況 2 ,函數功能相同,但參數個數不一樣,python 如何處理?你們知道,答案就是缺省參數。對那些缺乏的參數設定爲缺省參數便可解決問題。由於你假設函數功能相同,那麼那些缺乏的參數終歸是須要用的。
好了,鑑於狀況 1 跟 狀況 2 都有了解決方案,python 天然就不須要函數重載了。
問題能夠了解下(新式類是廣度優先,舊式類是深度優先),裏講的也不少.
15 __new__和__init__的區別
這個__new__確實不多見到,先作了解吧.
__new__是一個靜態方法,而__init__是一個實例方法.
__new__方法會返回一個建立的實例,而__init__什麼都不返回.
只有在__new__返回一個cls的實例時後面的__init__才能被調用.
當建立一個新實例時調用__new__,初始化一個實例時用__init__.
ps: __metaclass__是建立類時起做用.因此咱們能夠分別使用__metaclass__,__new__和__init__來分別在類建立,實例建立和實例初始化的時候作一些小手腳.
16 單例模式
這個絕對常考啊.絕對要記住1~2個方法,當時面試官是讓手寫的.
1 使用__new__方法
class Singleton(object):
def __new__(cls, *args, **kw):
if not hasattr(cls, '_instance'):
orig = super(Singleton, cls)
cls._instance = orig.__new__(cls, *args, **kw)
return cls._instance
class MyClass(Singleton):
a = 1
2 共享屬性
建立實例時把全部實例的__dict__指向同一個字典,這樣它們具備相同的屬性和方法.
class Borg(object):
_state = {}
def __new__(cls, *args, **kw):
ob = super(Borg, cls).__new__(cls, *args, **kw)
ob.__dict__ = cls._state
return ob
class MyClass2(Borg):
a = 1
3 裝飾器版本
def singleton(cls, *args, **kw):
instances = {}
def getinstance():
if cls not in instances:
instances[cls] = cls(*args, **kw)
return instances[cls]
return getinstance
@singleton
class MyClass:
...
4 import方法
做爲python的模塊是自然的單例模式
# mysingleton.py
class My_Singleton(object):
def foo(self):
pass
my_singleton = My_Singleton()
# to use
from mysingleton import my_singleton
my_singleton.foo()
17 Python中的做用域
Python 中,一個變量的做用域老是由在代碼中被賦值的地方所決定的。
當 Python 遇到一個變量的話他會按照這樣的順序進行搜索:
本地做用域(Local)→當前做用域被嵌入的本地做用域(Enclosing locals)→全局/模塊做用域(Global)→內置做用域(Built-in)
18 GIL線程全局鎖
線程全局鎖(Global Interpreter Lock),即Python爲了保證線程安全而採起的獨立線程運行的限制,說白了就是一個核只能在同一時間運行一個線程.
解決辦法就是多進程和下面的協程(協程也只是單CPU,可是能減少切換代價提高性能).
19 協程
簡單點說協程是進程和線程的升級版,進程和線程都面臨着內核態和用戶態的切換問題而耗費許多切換時間,而協程就是用戶本身控制切換的時機,再也不須要陷入系統的內核態.
Python裏最多見的yield就是協程的思想!能夠查看第九個問題.
20 閉包
閉包(closure)是函數式編程的重要的語法結構。閉包也是一種組織代碼的結構,它一樣提升了代碼的可重複使用性。
當一個內嵌函數引用其外部做做用域的變量,咱們就會獲得一個閉包. 總結一下,建立一個閉包必須知足如下幾點:
必須有一個內嵌函數
內嵌函數必須引用外部函數中的變量
外部函數的返回值必須是內嵌函數
感受閉包仍是有難度的,幾句話是說不明白的,仍是查查相關資料.
重點是函數運行後並不會被撤銷,就像16題的instance字典同樣,當函數運行完後,instance並不被銷燬,而是繼續留在內存空間裏.這個功能相似類裏的類變量,只不過遷移到了函數上.
閉包就像個空心球同樣,你知道外面和裏面,但你不知道中間是什麼樣.
21 lambda函數
其實就是一個匿名函數,爲何叫lambda?由於和後面的函數式編程有關.
推薦: 知乎3
22 Python函數式編程
這個須要適當的瞭解一下吧,畢竟函數式編程在Python中也作了引用.
python中函數式編程支持:
filter 函數的功能至關於過濾器。調用一個布爾函數bool_func來迭代遍歷每一個seq中的元素;返回一個使bool_seq返回值爲true的元素的序列。
>>>a = [1,2,3,4,5,6,7]
>>>b = filter(lambda x: x > 5, a)
>>>print b
>>>[6,7]
map函數是對一個序列的每一個項依次執行函數,下面是對一個序列每一個項都乘以2:
>>> a = map(lambda x:x*2,[1,2,3])
>>> list(a)
[2, 4, 6]
reduce函數是對一個序列的每一個項迭代調用函數,下面是求3的階乘:
>>> reduce(lambda x,y:x*y,range(1,4))
6
23 Python裏的拷貝
引用和copy(),deepcopy()的區別
import copy
a = [1, 2, 3, 4, ['a', 'b']] #原始對象
b = a #賦值,傳對象的引用
c = copy.copy(a) #對象拷貝,淺拷貝
d = copy.deepcopy(a) #對象拷貝,深拷貝
a.append(5) #修改對象a
a[4].append('c') #修改對象a中的['a', 'b']數組對象
print 'a = ', a
print 'b = ', b
print 'c = ', c
print 'd = ', d
輸出結果:
a = [1, 2, 3, 4, ['a', 'b', 'c'], 5]
b = [1, 2, 3, 4, ['a', 'b', 'c'], 5]
c = [1, 2, 3, 4, ['a', 'b', 'c']]
d = [1, 2, 3, 4, ['a', 'b']]
24 Python垃圾回收機制
Python GC主要使用引用計數(reference counting)來跟蹤和回收垃圾。在引用計數的基礎上,經過「標記-清除」(mark and sweep)解決容器對象可能產生的循環引用問題,經過「分代回收」(generation collection)以空間換時間的方法提升垃圾回收效率。
1 引用計數
PyObject是每一個對象必有的內容,其中ob_refcnt就是作爲引用計數。當一個對象有新的引用時,它的ob_refcnt就會增長,當引用它的對象被刪除,它的ob_refcnt就會減小.引用計數爲0時,該對象生命就結束了。
優勢:
簡單
實時性
缺點:
維護引用計數消耗資源
循環引用
2 標記-清除機制
基本思路是先按需分配,等到沒有空閒內存的時候從寄存器和程序棧上的引用出發,遍歷以對象爲節點、以引用爲邊構成的圖,把全部能夠訪問到的對象打上標記,而後清掃一遍內存空間,把全部沒標記的對象釋放。
3 分代技術
分代回收的總體思想是:將系統中的全部內存塊根據其存活時間劃分爲不一樣的集合,每一個集合就成爲一個「代」,垃圾收集頻率隨着「代」的存活時間的增大而減少,存活時間一般利用通過幾回垃圾回收來度量。
Python默認定義了三代對象集合,索引數越大,對象存活時間越長。
舉例:
當某些內存塊M通過了3次垃圾收集的清洗以後還存活時,咱們就將內存塊M劃到一個集合A中去,而新分配的內存都劃分到集合B中去。當垃圾收集開始工做時,大多數狀況都只對集合B進行垃圾回收,而對集合A進行垃圾回收要隔至關長一段時間後才進行,這就使得垃圾收集機制須要處理的內存少了,效率天然就提升了。在這個過程當中,集合B中的某些內存塊因爲存活時間長而會被轉移到集合A中,固然,集合A中實際上也存在一些垃圾,這些垃圾的回收會由於這種分代的機制而被延遲。
26 Python的is
is是對比地址,==是對比值
27 read,readline和readlines
read 讀取整個文件
readline 讀取下一行,使用生成器方法
readlines 讀取整個文件到一個迭代器以供咱們遍歷
解釋一下 Django 和 Tornado 的關係、差異
Django源自一個在線新聞 Web站點,於 2005 年以開源的形式被釋放出來。
Django 框架的核心組件有:
用於建立模型的對象關係映射爲最終用戶設計的完美管理界面一流的 URL 設計設計者友好的模板語言緩存系統等等
它鼓勵快速開發,並遵循MVC設計。Django遵照 BSD版權,最新發行版本是Django
1.4,於2012年03月23日發佈.Django的主要目的是簡便、快速的開發數據庫驅動的網站。它強調代碼複用,多個組件能夠很方便的以「插件」形式服務於整個框架,Django有許多功能強大的第三方插件,你甚至能夠很方便的開發出本身的工具包。這使得Django具備很強的可擴展性。它還強調快速開發和DRY(Do Not RepeatYourself)原則。
Tornado是 FriendFeed使用的可擴展的非阻塞式 web 服務器及其相關工具的開源版本。這個 Web 框架看起來有些像 web.py 或者 Google 的 webapp,不過爲了能有效利用非阻塞式服務器環境,這個 Web 框架還包含了一些相關的有用工具和優化。
Tornado 和如今的主流 Web 服務器框架(包括大多數Python 的框架)有着明顯的區別:它是非阻塞式服務器,並且速度至關快。得利於其 非阻塞的方式和對epoll的運用,Tornado 每秒能夠處理數以千計的鏈接,這意味着對於實時 Web服務來講,Tornado 是一個理想的 Web 框架。咱們開發這個 Web 服務器的主要目的就是爲了處理 FriendFeed 的實時功能 ——在 FriendFeed 的應用裏每個活動用戶都會保持着一個服務器鏈接。(關於如何擴容 服務器,以處理數以千計的客戶端的鏈接的問題。
解釋下django-debug-toolbar的使用
使用django開發站點時,能夠使用django-debug-toolbar來進行調試。在settings.py中添加’debug_toolbar.middleware.DebugToolbarMiddleware’到項目的MIDDLEWARE_CLASSES 內。
解釋下Django使用redis緩存服務器
爲了能在Django中使用redis,還須要安裝redis for Django的插件。而後在Django的settings中配置了。如今鏈接和配置都已經完成了,接下來是一個簡單的例子:
解釋下Http協議
HTTP是一個屬於應用層的面向對象的協議,因爲其簡捷、快速的方式,適用於分佈式超媒體信息系統。
HTTP協議的主要特色可歸納以下:
1.支持客戶/服務器模式。
2.簡單快速:客戶向服務器請求服務時,只需傳送請求方法和路徑。請求方法經常使用的有GET、HEAD、POST。每種方法規定了客戶與服務器聯繫的類型不一樣。因爲HTTP協議簡單,使得HTTP服務器的程序規模小,於是通訊速度很快。
3.靈活:HTTP容許傳輸任意類型的數據對象。正在傳輸的類型由Content-Type加以標記。
4.無鏈接:無鏈接的含義是限制每次鏈接只處理一個請求。服務器處理完客戶的請求,並收到客戶的應答後,即斷開鏈接。採用這種方式能夠節省傳輸時間。
5.無狀態:HTTP協議是無狀態協議。無狀態是指協議對於事務處理沒有記憶能力。缺乏狀態意味着若是後續處理須要前面的信息,則它必須重傳,這樣可能致使每次鏈接傳送的數據量增大。另外一方面,在服務器不須要先前信息時它的應答就較快。
解釋下Http請求頭和常見響應狀態碼
Accept:指瀏覽器或其餘客戶能夠接愛的MIME文件格式。能夠根據它判斷並返回適當的文件格式。
Accept-Charset:指出瀏覽器能夠接受的字符編碼。英文瀏覽器的默認值是ISO-8859-1.
Accept-Language:指出瀏覽器能夠接受的語言種類,如en或en-us,指英語。
Accept-Encoding:指出瀏覽器能夠接受的編碼方式。編碼方式不一樣於文件格式,它是爲了壓縮文件並加速文件傳遞速度。瀏覽器在接收到Web響應以後先解碼,而後再檢查文件格式。
Cache-Control:設置關於請求被代理服務器存儲的相關選項。通常用不到。
Connection:用來告訴服務器是否能夠維持固定的HTTP鏈接。HTTP/1.1使用Keep-Alive爲默認值,這樣,當瀏覽器須要多個文件時(好比一個HTML文件和相關的圖形文件),不須要每次都創建鏈接。
Content-Type:用來表名request的內容類型。能夠用HttpServletRequest的getContentType()方法取得。
Cookie:瀏覽器用這個屬性向服務器發送Cookie。Cookie是在瀏覽器中寄存的小型數據體,它能夠記載和服務器相關的用戶信息,也能夠用來實現會話功能。
狀態代碼有三位數字組成,第一個數字定義了響應的類別,且有五種可能取值:
1xx:指示信息–表示請求已接收,繼續處理
2xx:成功–表示請求已被成功接收、理解、接受
3xx:重定向–要完成請求必須進行更進一步的操做
4xx:客戶端錯誤–請求有語法錯誤或請求沒法實現
5xx:服務器端錯誤–服務器未能實現合法的請求
常見狀態代碼、狀態描述、說明:
200 OK //客戶端請求成功
400 Bad Request //客戶端請求有語法錯誤,不能被服務器所理解
401 Unauthorized //請求未經受權,這個狀態代碼必須和WWW-Authenticate報頭域一塊兒使用
403 Forbidden //服務器收到請求,可是拒絕提供服務
404 Not Found //請求資源不存在,eg:輸入了錯誤的URL
500 Internal Server Error //服務器發生不可預期的錯誤
503 Server Unavailable //服務器當前不能處理客戶端的請求,一段時間後可能恢復正常
eg:HTTP/1.1 200 OK (CRLF)
1.python下多線程的限制以及多進程中傳遞參數的方式?
python多線程有個全局解釋器鎖(global interpreter lock),這個鎖的意思是任一時間只能有一個線程使用解釋器,跟單cpu跑多個程序一個意思,你們都是輪着用的,這叫「併發」,不是「並行」。
多進程間共享數據,能夠使用 multiprocessing.Value 和 multiprocessing.Array
試題NO.02
2.Python是如何進行內存管理的?
Python引用了一個內存池(memory pool)機制,即Pymalloc機制(malloc:n.分配內存),用於管理對小塊內存的申請和釋放
內存池(memory pool)的概念:
當 建立大量消耗小內存的對象時,頻繁調用new/malloc會致使大量的內存碎片,導致效率下降。內存池的概念就是預先在內存中申請必定數量的,大小相等 的內存塊留做備用,當有新的內存需求時,就先從內存池中分配內存給這個需求,不夠了以後再申請新的內存。這樣作最顯著的優點就是可以減小內存碎片,提高效率。
內存池的實現方式有不少,性能和適用範圍也不同。
python中的內存管理機制——Pymalloc:
python中的內存管理機制都有兩套實現,一套是針對小對象,就是大小小於256bits時,pymalloc會在內存池中申請內存空間;當大於256bits,則會直接執行new/malloc的行爲來申請內存空間。 關於釋放內存方面,當一個對象的引用計數變爲0時,python就會調用它的析構函數。在析構時,也採用了內存池機制,從內存池來的內存會被歸還到內存池中,以免頻繁地釋放動做。
試題NO.03
3.什麼是lambda函數?它有什麼好處?
lambda 函數是一個能夠接收任意多個參數(包括可選參數)而且返回單個表達式值的函數。 lambda 函數不能包含命令,它們所包含的表達式不能超過一個。不要試圖向lambda 函數中塞入太多的東西;若是你須要更復雜的東西,應該定義一個普通函數,而後想讓它多長就多長。
試題NO.04
4.如何用Python輸出一個Fibonacci數列?
1 a,b = 0, 1
2 while b<100:
3 print (b),
4 a, b = b, a+b
試題NO.05
5.介紹一下Python中webbrowser的用法?
webbrowser模塊提供了一個高級接口來顯示基於Web的文檔,大部分狀況下只須要簡單的調用open()方法。
webbrowser定義了以下的異常:
exception webbrowser.Error, 當瀏覽器控件發生錯誤是會拋出這個異常
webbrowser有如下方法:
webbrowser.open(url[, new=0[, autoraise=1]])
這個方法是在默認的瀏覽器中顯示url, 若是new = 0, 那麼url會在同一個瀏覽器窗口下打開,若是new = 1, 會打開一個新的窗口,若是new = 2, 會打開一個新的tab, 若是autoraise = true, 窗口會自動增加。
webbrowser.open_new(url)
在默認瀏覽器中打開一個新的窗口來顯示url, 不然,在僅有的瀏覽器窗口中打開url
webbrowser.open_new_tab(url)
在默認瀏覽器中當開一個新的tab來顯示url, 不然跟open_new()同樣
webbrowser.get([name]) 根據name返回一個瀏覽器對象,若是name爲空,則返回默認的瀏覽器
webbrowser.register(name, construtor[, instance])
註冊一個名字爲name的瀏覽器,若是這個瀏覽器類型被註冊就能夠用get()方法來獲取。
試題NO.06
6.解釋一下python的and-or語法
與C表達式 bool ? a : b相似,可是bool and a or b,當 a 爲假時,不會象C表達式 bool ? a : b 同樣工做
應該將 and-or 技巧封裝成一個函數:
def choose(bool, a, b):
return (bool and [a] or [b])[0]
由於 [a] 是一個非空列表,它永遠不會爲假。甚至 a 是 0 或 '' 或其它假值,列表[a]爲真,由於它有一個元素。
試題NO.07
7.how do I iterate over a sequence in reverse order?
for x in reversed(sequence):
... # do something with x..
若是不是list, 最通用可是稍慢的解決方案是:
for i in range(len(sequence)-1, -1, -1):
x = sequence[i]
<do something with x>
試題NO.08
8.Python是如何進行類型轉換的?
試題NO.09
9.Python裏面如何實現tuple和list的轉換?
試題NO.10
10.請寫出一段Python代碼實現刪除一個list裏面的重複元素?
試題NO.11
11.Python如何實現單例模式?其餘23種設計模式python如何實現?
試題NO.12
12.Python裏面如何拷貝一個對象?
標準庫中的copy模塊提供了兩個方法來實現拷貝.一個方法是copy,它返回和參數包含內容同樣的對象.
使用deepcopy方法,對象中的屬性也被複制
試題NO.13
13.如何用Python來進行查詢和替換一個文本字符串?
能夠使用sub()方法來進行查詢和替換,sub方法的格式爲:sub(replacement, string[, count=0])
replacement是被替換成的文本
string是須要被替換的文本
count是一個可選參數,指最大被替換的數量
14.Python裏面search()和match()的區別?
match()函數只檢測RE是否是在string的開始位置匹配,search()會掃描整個string查找匹配, 也就是說match()只有在0位置匹配成功的話纔有返回,若是不是開始位置匹配成功的話,match()就返回none 。
試題NO.15
微軟十五道面試題
1、有一個整數數組,請求出兩兩之差絕對值最小的值,
記住,只要得出最小值便可,不須要求出是哪兩個數。
##############通常解法################
def foo(data1,data2):
min=abs(data1[0]-data2[0])
for i in data1:
for j in data2:
if abs(i-j)<min:
min=abs(i-j)
return min
a=[132,43,-1876,565,1]
b=[85,-63443,569,-1899,135]
c=foo(a,b)
print c
#################oneliner#####################
>>> a=[132,43,-1876,565,1]
>>> b=[85,-63443,569,-1899,135]
>>> c=min(abs(i-j) for i in a for j in b)
>>> c
3
這裏有一個技巧,[abs(i-j) for i in a for j in b]會生成一個list,使用大量的存儲空間,而(abs(i-j) for i in a for j in b)則產生一個生成器。
2、寫一個函數,檢查字符是不是整數,若是是,返回其整數值。(或者:怎樣只用4行代碼編寫出一個從字符串到長整形的函數?)
用python解這題很方便,內置函數isdigit()和int()能夠實現:
a=raw_input('a:')
print type(a)
print a.isdigit()
a=int(a)
print type(a)
結果以下:
a:43627856823958612387568912365
<type'str'>
True
<type'long'>
3、給出一個函數來輸出一個字符串的全部排列。
這題一看就是各類迭代吧,天然想到一個python標準庫--itertools:
from itertools import permutations
>>> a='nice'
>>> for element in list(itertools.permutations(a, 4)):
print ''.join(element),' ',
nice niec ncie ncei neic neci ince inec icne icen ienc iecn cnie cnei cine cien ceni cein enic enci einc eicn ecni ecin
4、給出一個函數來複制兩個字符串A和B。字符串A的後幾個字節和字符串B的前幾個字節重疊
基本思路:
先判斷兩個字符串長度,再使用內置函數a.endswith()或b.startswith()尋找重疊部分。
a='abcdefghijklmnop'
b='ijklmnopqrstuvwxyz'
minlen=min(len(a),len(b))
i=0
while i:
if a.endswith(b[:i+1]):
break
else:
i+=1
if i== minlen:
newstr=a+b
else:
newstr=a+b[i+1:]
print newstr
5、怎樣編寫一個程序,把一個有序整數數組放到二叉樹中?
6、怎樣從頂部開始逐層打印二叉樹結點數據?請編程。
Python的二叉樹尚未研究過。。。先放一下。。。
7、怎樣把一個鏈表掉個順序(也就是反序,注意鏈表的邊界條件並考慮空鏈表)?
使用內置reverse()函數或者使用a[-1::-1]均可以
8、請編寫能直接實現int atoi(const char * pstr)函數功能的代碼。
不適用int()函數。考慮兩種狀況:輸入‘1234’,輸出1234;輸入‘1234.56’,輸出‘1234’。
‘1’腫麼轉換成1?ord('1')-ord('0')
def my_atoi(data):
integer=data.split('.')[0]
result=0
for i,ele in enumerate(integer):
result+=(ord(ele)-ord('0'))*10**(len(integer)-i-1)
return result
a='1234'
b='1234.56'
print my_atoi(a)
print my_atoi(b)
10、在排序數組中,找出給定數字的出現次數
好比 [1, 2, 2, 2, 3] 中2的出現次數是3次。
內置函數count()
11、平面上N個點,每兩個點都肯定一條直線,
求出斜率最大的那條直線所經過的兩個點(斜率不存在的狀況不考慮)。時間效率越高越好。
一樣使用itertools庫,方便的兩兩組合N個點
from itertools import combinations
A=(1,4)
B=(2,1)
C=(4,3)
D=(5,5)
E=(8,2)
name='ABCDE'
pos=[A,B,C,D,E]
name_com=combinations(name,2)
pos_com=combinations(pos,2)
def cal_rate(data1,data2):
return (data1[1]-data2[1])/(data1[0]-data2[0])
rates=[]
for ele in list(pos_com):
rates.append(cal_rate(ele[0],ele[1]))
print rates
print rates.index(max(rates))
print list(name_com)[rates.index(max(rates))]
運行結果:
[-3, -1, 0, -1, 1, 1, 0, 2, -1, -1]
7
('C', 'D')
12、一個整數數列,元素取值多是0~65535中的任意一個數,相同數值不會重複出現。0是例外,能夠反覆出現。
請設計一個算法,當你從該數列中隨意選取5個數值,判斷這5個數值是否連續相鄰。
注意:
- 5個數值容許是亂序的。好比: 8 7 5 0 6
- 0能夠通配任意數值。好比:8 7 5 0 6 中的0能夠通配成9或者4
- 0能夠屢次出現。
- 複雜度若是是O(n2)則不得分。
個人思路:無論有幾個零,非零整數兩兩之差最大值小於等於4。所以作一次循環,求出數列中的最大值和最小值,二者相減便可。這裏須要考慮的細節是求出去零之外的最小值以及數列若是全零的狀況。
a=[1,4,5,2,3]
b=[0,0,0,0,0]
c=[6,1,0,2,5]
d=[4,0,7,8,0]
def foo(data):
maxint=max(data)
minint=maxint
if minint==0:
return True
else:
for i in data:
if i<minint:
minint=i
if maxint-minint<=4:
return True
else:
return False
print foo(a) #True
print foo(b) #True
print foo(c) #False
print foo(d) #False
其實這裏還有一個問題,如何產生隨機數列,且零能重複,其餘數字不能重複。
from random import randint
array=[]
while len(array)<=5:
x=randint(0,65535)
if x==0 or x not in array:
array.append(x)
浪漫殺手 2012-10-13 11:27:37
Python面試題:請寫出一段Python代碼實現刪除一個list裏面的重複元素:
1、本身的思路:
遍歷列表,發現元素不一樣,添加到新列表C中。
最後將C列表賦值給原列表
def select(a):
i=None
c=[]
for b in a:
if i!=b:
c.append(b)
i=b
a[0:]=c
自我總結:
1.
迭代器的迭代方式(按索引迭代)
for b in c:
print str(b)
這種迭代方式是按索引來的。
若是在迭代過程當中對原列表進行操做,會產生奇怪的記過。
例子:
>>> c=[1,2,3,4]
>>> for b in c:
print "before:"+str(b)
c.remove(b)
print "after:"+str(b)
before:1
after:1
before:3
after:3
從這個例子能學到:若是在迭代時刪除某個元素,會致使列表改變,可是迭代器依舊以原來的索引順序迭代,這會致使數據錯位,引發bug
2.編寫循環邏輯注意點:
通常只是簡單的for循環是比較簡單的,可是若是伴隨着相應變量的變動,變量的讀取,就會比較容易出錯。
2.1怎麼減少錯誤呢?.最簡單的方法,畫圖,一個循環一個圖,就比較容易想清楚了。
2.2怎麼提升編程能力?特別面對循環時?
首先,是積累,腦子裏須要創建一個知識庫。(相似的問題該怎麼解決)
其次,是在編程時,用到積累的知識須要和環境結合,可能思惟會亂,能夠畫圖
最後,就是概括第二步的思惟,這樣就能寫出程序了
3.參數傳遞,與值的改變
若是a引用了一個對象,那麼將a傳入select函數。在select改變行參的值不影響外界a的值。
只有改變a所指向內存的值,才能改變a的值
4.當對數據進行操做時,須要考慮此操做是否會影響之後的操做。
二:網上比較好的答案:
思路:從後往前,遍歷,這樣刪除元素此也不會影響之後遍歷時取值的操做
代碼:
def sort_select(a):
if not a: print 'there is nothing in a'
else:
temp = a[-1]
for i in range(len(a)-2,-1,-1):
if a[i]==temp:del a[i]
else:temp=a[i]
總結:
range函數的起始於結束:
for i in range(100):
print str(i)
輸出結果:打印從1到99
for i in range(5,-1,-1):
print str(i)
輸出結果:打印從5到0
碰到這種問題的經驗:
1.要用循環
2.由於是對列表刪除操做,又要遍歷整個列表,因此從後往前遍歷比較好,就算刪除了後面的元素,也不會影響前面元素的順序
3.首先一箇中間值(temp),temp等於該列表的最後一個值。
將temp與從後往前遍從來的值對比
若是 相等,就刪除
不然 就 將值賦給temp,一邊下次循環比較
簡述__new__和__init__的區別
建立一個新實例時調用__new__,初始化一個實例時用__init__,這是它們最本質的區別。
new方法會返回所構造的對象,init則不會.
new函數必須以cls做爲第一個參數,而init則以self做爲其第一個參數
如何捕獲異常,經常使用的異常機制有哪些?
若是咱們沒有對異常進行任何預防,那麼在程序執行的過程當中發生異常,就會中斷程序,調用python默認的異常處理器,並在終端輸出異常信息。
try…except…finally語句:當try語句執行時發生異常,回到try語句層,尋找後面是否有except語句。找到except語句後,會調用這個自定義的異常處理器。except將異常處理完畢後,程序繼續往下執行。finally語句表示,不管異常發生與否,finally中的語句都要執行。
assert語句:判斷assert後面緊跟的語句是True仍是False,若是是True則繼續執行print,若是是False則中斷程序,調用默認的異常處理器,同時輸出assert語句逗號後面的提示信息。
with語句:若是with語句或語句塊中發生異常,會調用默認的異常處理器處理,但文件仍是會正常關閉。
1 b 2b 3.b4a5c6a7c
高德軟件有限公司python試題 及 答案
本文地址: http://blog.csdn.net/caroline_wendy/article/details/25230835
by Spike 2014.5.7
本題目僅供學術交流, 嚴禁用於其餘目的, 答案僅供參考.
1. 在Python中, list, tuple, dict, set有什麼區別, 主要應用在什麼樣的場景?
解答:
定義:
list: 鏈表, 有序的項目, 經過索引進行查找, 使用方括號"[]";
tuple: 元組, 元組將多樣的對象集合到一塊兒, 不能修改, 經過索引進行查找, 使用括號"()";
dict: 字典, 字典是一組鍵(key)和值(value)的組合, 經過鍵(key)進行查找, 沒有順序, 使用大括號"{}";
set: 集合,無序, 元素只出現一次, 自動去重, 使用"set([])";
應用場景:
list, 簡單的數據集合, 能夠使用索引;
tuple, 把一些數據當作一個總體去使用, 不能修改;
dict, 使用鍵值和值進行關聯的數據;
set, 數據只出現一次, 只關心數據是否出現, 不關心其位置;
代碼:
[python] view plain copy print?
mylist = [1, 2, 3, 4, 'Oh']
mytuple = (1, 2, 'Hello', (4, 5))
mydict = {'Wang' : 1, 'Hu' : 2, 'Liu' : 4}
myset = set(['Wang', 'Hu', 'Liu', 4, 'Wang'])
mylist = [1, 2, 3, 4, 'Oh']
mytuple = (1, 2, 'Hello', (4, 5))
mydict = {'Wang' : 1, 'Hu' : 2, 'Liu' : 4}
myset = set(['Wang', 'Hu', 'Liu', 4, 'Wang'])
2. 靜態函數, 類函數, 成員函數的區別?
解答:
定義:
靜態函數(@staticmethod): 即靜態方法,主要處理與這個類的邏輯關聯;
類函數(@classmethod): 即類方法, 更關注於從類中調用方法, 而不是在實例中調用方法, 能夠用做方法重載, 傳入參數cls;
成員函數: 實例的方法, 只能經過實例進行調用;
具體應用:
日期的方法, 能夠經過實例化(__init__)進行數據輸出, 傳入參數self;
能夠經過類的方法(@classmethod)進行數據轉換, 傳入參數cls;
能夠經過靜態方法(@staticmethod)進行數據驗證;
代碼:
[python] view plain copy print?
# -*- coding: utf-8 -*-
#eclipse pydev, python 3.3
#by C.L.Wang
class Date(object):
day = 0
month = 0
year = 0
def __init__(self, day=0, month=0, year=0):
self.day = day
self.month = month
self.year = year
def display(self):
return "{0}*{1}*{2}".format(self.day, self.month, self.year)
@classmethod
def from_string(cls, date_as_string):
day, month, year = map(int, date_as_string.split('-'))
date1 = cls(day, month, year)
return date1
@staticmethod
def is_date_valid(date_as_string):
day, month, year = map(int, date_as_string.split('-'))
return day <= 31 and month <= 12 and year <= 3999
date1 = Date('12', '11', '2014')
date2 = Date.from_string('11-13-2014')
print(date1.display())
print(date2.display())
print(date2.is_date_valid('11-13-2014'))
print(Date.is_date_valid('11-13-2014'))
# -*- coding: utf-8 -*-
#eclipse pydev, python 3.3
#by C.L.Wang
class Date(object):
day = 0
month = 0
year = 0
def __init__(self, day=0, month=0, year=0):
self.day = day
self.month = month
self.year = year
def display(self):
return "{0}*{1}*{2}".format(self.day, self.month, self.year)
@classmethod
def from_string(cls, date_as_string):
day, month, year = map(int, date_as_string.split('-'))
date1 = cls(day, month, year)
return date1
@staticmethod
def is_date_valid(date_as_string):
day, month, year = map(int, date_as_string.split('-'))
return day <= 31 and month <= 12 and year <= 3999
date1 = Date('12', '11', '2014')
date2 = Date.from_string('11-13-2014')
print(date1.display())
print(date2.display())
print(date2.is_date_valid('11-13-2014'))
print(Date.is_date_valid('11-13-2014'))
3. a=1, b=2, 不用中間變量交換a和b的值
解答:
兩種形式: 加法或異或
代碼:
[python] view plain copy print?
a = 1
b = 2
a = a + b
b = a - b
a = a - b
print ('a = {0}, b = {1}'.format(a, b))
a = a ^ b
b = a ^ b
a = a ^ b
print ('a = {0}, b = {1}'.format(a, b))
a = 1
b = 2
a = a + b
b = a - b
a = a - b
print ('a = {0}, b = {1}'.format(a, b))
a = a ^ b
b = a ^ b
a = a ^ b
print ('a = {0}, b = {1}'.format(a, b))
4. 寫一個函數, 輸入一個字符串, 返回倒序排列的結果: 如: string_reverse(‘abcdef’), 返回: ‘fedcba’
(請採用多種方法實現, 並對實現方法進行比較)
解答:
5種方法的比較:
1. 簡單的步長爲-1, 即字符串的翻轉;
2. 交換先後字母的位置;
3. 遞歸的方式, 每次輸出一個字符;
4. 雙端隊列, 使用extendleft()函數;
5. 使用for循環, 從左至右輸出;
代碼:
[python] view plain copy print?
string = 'abcdef'
def string_reverse1(string):
return string[::-1]
def string_reverse2(string):
t = list(string)
l = len(t)
for i,j in zip(range(l-1, 0, -1), range(l//2)):
t[i], t[j] = t[j], t[i]
return "".join(t)
def string_reverse3(string):
if len(string) <= 1:
return string
return string_reverse3(string[1:]) + string[0]
from collections import deque
def string_reverse4(string):
d = deque()
d.extendleft(string)
return ''.join(d)
def string_reverse5(string):
#return ''.join(string[len(string) - i] for i in range(1, len(string)+1))
return ''.join(string[i] for i in range(len(string)-1, -1, -1))
print(string_reverse1(string))
print(string_reverse2(string))
print(string_reverse3(string))
print(string_reverse4(string))
print(string_reverse5(string))
string = 'abcdef'
def string_reverse1(string):
return string[::-1]
def string_reverse2(string):
t = list(string)
l = len(t)
for i,j in zip(range(l-1, 0, -1), range(l//2)):
t[i], t[j] = t[j], t[i]
return "".join(t)
def string_reverse3(string):
if len(string) <= 1:
return string
return string_reverse3(string[1:]) + string[0]
from collections import deque
def string_reverse4(string):
d = deque()
d.extendleft(string)
return ''.join(d)
def string_reverse5(string):
#return ''.join(string[len(string) - i] for i in range(1, len(string)+1))
return ''.join(string[i] for i in range(len(string)-1, -1, -1))
print(string_reverse1(string))
print(string_reverse2(string))
print(string_reverse3(string))
print(string_reverse4(string))
print(string_reverse5(string))
5. 請用本身的算法, 按升序合併以下兩個list, 並去除重複的元素:
list1 = [2, 3, 8, 4, 9, 5, 6]
list2 = [5, 6, 10, 17, 11, 2]
解答:
合併鏈表, 遞歸的快速排序, 去重連接;
代碼:
[python] view plain copy print?
import random
list1 = [2, 3, 8, 4, 9, 5, 6]
list2 = [5, 6, 10, 17, 11, 2]
def qsort(L):
if len(L)<2: return L
pivot_element = random.choice(L)
small = [i for i in L if i< pivot_element]
large = [i for i in L if i> pivot_element]
return qsort(small) + [pivot_element] + qsort(large)
def merge(list1, list2):
return qsort(list1 + list2)
print(merge(list1, list2))
import random
list1 = [2, 3, 8, 4, 9, 5, 6]
list2 = [5, 6, 10, 17, 11, 2]
def qsort(L):
if len(L)<2: return L
pivot_element = random.choice(L)
small = [i for i in L if i< pivot_element]
large = [i for i in L if i> pivot_element]
return qsort(small) + [pivot_element] + qsort(large)
def merge(list1, list2):
return qsort(list1 + list2)
print(merge(list1, list2))
注: 若是使用set方法, list(set(list1 + list2)), 便可.
6. 請寫出打印結果
x = [0, 1]
i = 0
i, x[i] = 1, 2
print(x)
打印結果: [0, 2], python能夠使用連續賦值, 從左至右.
g = lambda x, y=2, z : x + y**z
g(1, z=10) = ?
打印結果: 異常, 形參表末尾才能夠有默認參數, z須要提供默認參數.
7. 說一下如下代碼片斷存在的問題
[python] view plain copy print?
from amodule import * # amodule is an exist module
class dummyclass(object):
def __init__(self):
self.is_d = True
pass
class childdummyclass(dummyclass):
def __init__(self, isman):
self.isman = isman
@classmethod
def can_speak(self): return True
@property
def man(self): return self.isman
if __name__ == "__main__":
object = new childdummyclass(True)
print object.can_speak()
print object.man()
print object.is_d
from amodule import * # amodule is an exist module
class dummyclass(object):
def __init__(self):
self.is_d = True
pass
class childdummyclass(dummyclass):
def __init__(self, isman):
self.isman = isman
@classmethod
def can_speak(self): return True
@property
def man(self): return self.isman
if __name__ == "__main__":
object = new childdummyclass(True)
print object.can_speak()
print object.man()
print object.is_d
解答:
1. 警告: object是python新形式(new style)的一個基礎類, 不該該被從新定義;
2. 警告: 類方法(classmethod)是類所擁有的方法, 傳入的參數應該是cls, 而不是self;
3. 錯誤: Python沒有new關鍵字, 如需修改new, 如單例模式, 能夠重寫(override)__new__;
4. 錯誤: @property, 表示屬性, 不是方法, 則不須要加括號」()」, 直接調用object.man, 便可;
5. 錯誤: 若是想使用基類的成員, 則須要初始化基類, 如dummyclass.__init__(self), 便可;
6. 額外: 類名儘可能使用大寫.
代碼:
[python] view plain copy print?
class dummyclass(object):
def __init__(self):
self.is_d = True
pass
class childdummyclass(dummyclass):
def __init__(self, isman):
dummyclass.__init__(self) #__init__
self.isman = isman
@classmethod
def can_speak(cls): return True #cls
@property
def man(self): return self.isman
if __name__ == "__main__":
o = childdummyclass(True) #new, object
print o.can_speak()
print o.man #property
print o.is_d
class dummyclass(object):
def __init__(self):
self.is_d = True
pass
class childdummyclass(dummyclass):
def __init__(self, isman):
dummyclass.__init__(self) #__init__
self.isman = isman
@classmethod
def can_speak(cls): return True #cls
@property
def man(self): return self.isman
if __name__ == "__main__":
o = childdummyclass(True) #new, object
print o.can_speak()
print o.man #property
print o.is_d
8. 介紹一下python的異常處理機制和本身開發過程當中的體會
解答:
Python的異常處理機制:
try: 嘗試拋出異常;
raise: 引起異常;
except: 處理異常;
finally: 是否發生異常都須要作的事情;
建立新的異常類型, 須要繼承Exception類, 能夠定義類的屬性, 便於處理異常;
開發體會:
異常主要處理讀取文件, 也能夠使用with的方法讀取文件; 還能夠用於網絡鏈接, 異常能夠包含大量的錯誤信息, 進行錯誤處理.
代碼:
[python] view plain copy print?
class ShortInputException(Exception):
def __init__(self, length, atleast):
Exception.__init__(self)
self.length = length
self.atleast = atleast
while True:
try:
text = raw_input('Enter somthing-->')
if len(text) < 3:
raise ShortInputException(len(text), 3)
except EOFError:
print('Why did you do an EOF on me')
except ShortInputException as ex:
print('ShortInputException The input was {0} long, \
excepted at least {1}. '.format(ex.length, ex.atleast))
else:
print('No exception was raised. ')
finally:
print('Over')
class ShortInputException(Exception):
def __init__(self, length, atleast):
Exception.__init__(self)
self.length = length
self.atleast = atleast
while True:
try:
text = raw_input('Enter somthing-->')
if len(text) < 3:
raise ShortInputException(len(text), 3)
except EOFError:
print('Why did you do an EOF on me')
except ShortInputException as ex:
print('ShortInputException The input was {0} long, \
excepted at least {1}. '.format(ex.length, ex.atleast))
else:
print('No exception was raised. ')
finally:
print('Over')
# -*- coding: gbk -*-
def print_prime_factors(num):
if num < 2:
print '請輸入大於 1 的整數用於質因數分解'
return
print '輸出:',
prime_num = 2
while prime_num <= num:
if prime_num == num:
print prime_num,
break
elif num % prime_num == 0:
print prime_num,
num /= prime_num
else:
prime_num += 1
if __name__ == '__main__':
num = int(raw_input('輸入:'))
print_prime_factors(num)
第一題: give you two var a and b, print the value of a+b, just do it!
根據提議,給出兩個變量 a 和 b 並打印出 a+b的值.
1 2 |
a, b = 1, 2 print a + b |
固然也能夠這麼作
1 2 3 |
a = 1 b = 2 print a + b |
第二題: 給你一個list, 如 L = [2, 8, 3, 5], 對L進行升序排序並輸出。
1 2 3 4 5 6 |
L = sorted(L) print L #或 # sort() 內置函數會對列表自身排序而 sorted() 會生成一個新的排序列表 L.sort() print L |
第三題: 給你一個字符串a, 如a = ‘12345', 對a進行逆序輸出。
1 2 3 |
# 經過步進來逆序輸出字符串。 a = a[::-1] print a |
第四題: 給你一個字典a = {1:1, 2:2, 3:3}, 輸出字典a的key ,以',' 鏈接,如 ‘1,2,3'。
1 2 |
# dict.keys() 會以list返回字典的key.而join會把list按,字符串',' 鏈接起來。 print ','.join(a.keys()) |
第五題: 給你一個字符串a, 輸出字符串奇數位置的字符串,如 a = ‘12345', 則輸出 ‘135'
1 2 |
# 經過列表解析(也稱列表推導式)來判斷下表選取奇偶數。 print ''.join([a[x] for x in range(len(a)) if x % 2 == 0]) |
第六題: 輸出全部100之內的素數, 素數之間以空格區分。
1 2 3 4 5 |
# 在加一行print 才能運行經過 L = [x for x in range(2, 101) if not [y for y in range(2, x) if x%y == 0]] for i in L: print L, |
第七題: 已知矩形長a, 寬b, 輸出其面積和周長,以一個空格隔開
1 |
print a * b, 2 * (a+b) |
第八題: 給你一個list, 如 L = [0, 1, 2, 3, 4] 輸出L的中位數
1 2 3 |
# 中位數是指 對已排序的數集取其中間數,數集爲偶數 取中間兩數的平均 print sorted(L)[len(L)/2] if len(L) % 2 != 0 else \ (sorted(L)[Len(L)/2] + sorted(L)[len(L)/2 -1 ])/2.0 |
第九題: 給你兩個正整數a和b, 輸出它們的最大公約數。
1 |
print max([x for x in range(1, a+1) if x in [y for y in range(1, b+1) if b%y == 0]]) |
第十題: 給你兩個正整數a和b, 輸出它們的最小公倍數.
1 |
print min([x for x in range(a, a*b+1) if x%a==0 and x%b==0]) |
附加題: 利用map/reduce 函數實現數的階乘 如 5!+4!+3!+2!+1!.
1 2 3 4 |
print map(lambda x: reduce(lambda y,z: y*z, range(1, x+1)), range(1,6)) # print [1, 2, 6, 24, 120], 因此在用reduce合起來 print reduce(lambda a, b: a+b, map(lambda x: \ reduce(lambda y, z: y*z, range(1, x+1)),range(1,6))) |
附加題: 使用filter函數 實現素數
1 |
print filter(lambda x: not [x%i for i in range(2,x) if x%i==0], range(2, 101)) |
15. def quickSort(Data,low,high):
45. def insertSort(Data):
61. def selectSort(Data):
77. def shellSort(Data):
1、填空題(每空1分,共24分)
1.Python使用符號 三引號 # 標示註釋;還有一種叫作’’’’’’的特別註釋。
2.表達式 1/4+2.75 的值是 2.75 ;
三、請給出計算231 −1的Python表達式 2**31-1 :
四、給出range(1,10,3)的值 (1,4,7)[1,4,7] :
五、Python的數據類型分爲整型 、 字符串型 、 浮點型
、複數等類型。
六、Python序列類型包括 元組 、 序列 、字典 三種;
字典 是Python中惟一的映射類型。
七、Python的除法運算符是 / ,取餘運算符是 % 。
八、設s=‘abcdefg’,則s[3]值是‘d’ ,s[3:5]值是 def ‘de’ ,s[:5]值是 abcdef’abcde’s[3:]值是 ‘defg’ ,s[::-1]值是 g 。’gfedcba’
九、刪除字典中的全部元素的函數是 def.dictclear()返回列表的函數是 key(),返回包含字典中全部值的列表的函數是 values()判斷鍵在字典中是否存在的函數是 has.dict(key) get()。
2、選擇題(每題3分,共36分)
1.下列哪一個語句在Python中是非法的? (C )B
A、x = y = z = 1 B、x = (y = z + 1)
C、x, y = y, x D、x += y
2.關於Python內存管理,下列說法錯誤的是 (B )
A、變量沒必要事先聲明 B、變量無須先建立和賦值而直接使用
C、變量無須指定類型 D、能夠使用del釋放資源
三、(1) 執行下列語句後的顯示結果是什麼? ( A)
>>> world=」world」
>>> print 「hello」+ world
A、 helloworld B、 「hello」world
C、hello world D、 語法錯誤
四、下面哪一個不是Python合法的標識符 B( )
A、int32 B、40XL C、self D、__name__
五、下列哪一種說法是錯誤的 A( )
A、除字典類型外,全部標準對象都可以用於布爾測試
B、空字符串的布爾值是False
C、空列表對象的布爾值是False
D、值爲0的任何數字對象的布爾值是False
六、下列表達式的值爲True的是 ( C )
A、5+4j > 2-3j B、3>2>2
C、(3,2)< (‘a’,’b’) D、’abc’ > ‘xyz’
七、Python不支持的數據類型有 A( )
A、char B、int C、float D、list
八、type(1+2L*3.14)的結果是: ( C )
[A] <type ‘int’>
[B] <type ‘long’>
[C] <type ‘float’>
[D] <type ‘str’>
九、關於字符串下列說法錯誤的是 (B )
A、字符應該視爲長度爲1的字符串
B、字符串以\0標誌字符串的結束
C、既能夠用單引號,也能夠用雙引號建立字符串
D、在三引號字符串中能夠包含換行回車等特殊字符
十、如下不能建立一個字典的語句是 ( C )
A、dict1 = {} B、dict2 = { 3 : 5 }
C、dict3 = dict( [2 , 5] ,[ 3 , 4 ] )
D、dict4 = dict( ( [1,2],[3,4] ) )
十一、下面不能建立一個集合的語句是 ( C)
A、s1 = set () B、s2 = set (「abcd」)
C、s3 = (1, 2, 3, 4) D、s4 = frozenset( (3,2,1) )
十二、下列Python語句正確的是 D( )
A、min = x if x < y else y B、max = x > y ? x : y
C、if (x > y) print x D、while True : pass
3、簡答題(每題8分,共40分)
一、編寫一個python程序,輸入兩個數,比較它們的大小並輸出其中較大者。
X=input(「輸入第一個數:」)
Y=input(「輸入第二個數:」)
If(x==y):
Print 「兩數相同」
Elif(x>y):
Print 「較大數爲x」
Else:
print「較大數爲y」
二、給定一個整數N,判斷N是否爲素數
三、存在字符串「I,love,python」,取出love,並輸出
S=」I,love,python」
A=S[2:6]
print A
四、用Python定義一個函數,輸入一年份,判斷該年份是不是閏年並輸出結果請輸入一個年份
Year=int(input(「請輸入年份:」))
if((year%4==0&&year%100!=0)||year%400==0)
if year%4==0 and year%100!=0 or year%100==0 :
print「是閏年「
else
print 「不是閏年「
五、存在字符串「ab2b3n5n2n67mm4n2」,編程統計字符串中字母n出現的次數
S= 「ab2b3n5n2n67mm4n2」
Count=0
For i in s[]
If s[i]==n
Count+=1
Print count
一. 選擇題: 將惟一正確的選項寫在題前括號中(每題1分,共15分)
【 】1.表達式 '%d%%%d' %(3 / 4, 3 % 4)的值是:
A.'0%3' B.'0%%3' C.'3/4%3%4' D.'3/4%%3%4'
【 】2.下面標識符中不是python語言的保留字的是:
A.continue B.except C.init D.pass
【 】3.如下程序的輸出結果是(提示:ord(' a ')==97):
lista = [1,2,3,4,5,'a','b','c','d','e']
print lista[2] + lista[5]
A.100 B.'d' C.d D.TypeEror
【 】4.下面的循環體執行的次數與其它不一樣的是:
A. i = 0
while( i <= 100):
print i,
i = i + 1
B. for i in range(100):
print i,
C. for i in range(100, 0, -1):
print i,
D. i = 100
while(i > 0):
print i,
i = i – 1
【 】5.自頂向下逐步求精的程序設計方法是指:
A.將一個大問題簡化爲一樣形式的較小問題。
B.先設計類,再實例化爲對象。
C.解決方案用若干個較小問題來表達,直至小問題很容易求解。
D.先設計簡單版本,再逐步增長功能。
【 】6.簡單變量做爲實參時,它和對應的形參之間數據傳遞方式是:
A.由形參傳給實參 B.由實參傳給形參
C.由實參傳給形參,再由形參傳給實參 D.由用戶指定傳遞方向
【 】7.如下說法不正確的是:
A.在不一樣函數中能夠使用相同名字的變量。
B.函數能夠減小代碼的重複,也使得程序能夠更加模塊化。
C.主調函數內的局部變量,在被調函數內不賦值也能夠直接讀取。
D.函數體中若是沒有return語句,也會返回一個None值。
【 】8.關於list和string下列說法錯誤的是:
A.list能夠存聽任意類型。
B.list是一個有序集合,沒有固定大小。
C.用於統計string中字符串長度的函數是string.len()。
D.string具備不可變性,其建立後值不能改變。
【 】9.下面問題屬於計算機本質上不可解問題的是:
A.Hanoi塔問題 B.排序問題 C.求階乘 D.Halting問題
【 】10.python語言定義的class的初始化函數的函數名是:
A.init B.__init__ C.__init D.init__
【 】11.已知x = 43,y = False;則表達式(x >= y and 'A' < 'B' and not y)的值是:
A.False B.語法錯 C.True D."假"
【 】12.對n個數作歸併排序(merge sort),這個算法是:
A.nlogn時間的 B.線性時間的 C.logn時間的 D.n2時間的
【 】13.下面不是計算思惟的特徵的是:
A.概念化 B.數學與工程思惟的融合 C.面向全部的人 D.計算機的思惟
【 】14.執行下面操做後,list2的值是:
list1 = [4,5,6]
list2 = list1
list1[2] = 3
A.[4,5,6] B.[4,3,6] C.[4,5,3] D.A,B,C都不正確
【 】15.下列合法的變量名是:
A.main( ) B.car2 C.2car D.var-name
二.概念填空(每空1分,共10分)
1.表達式eval("4 * 2 + 5 % 2 + 4/3")的結果是 。
2.print 'This float, %-10.5f, has width 10 and precision 5. ' % (3.1415926) 的輸出結果是:
3.計算的本質是 和 。
4.執行 print 1.3 - 1 == 0.3,結果是False的緣由是 。
5.下面語句的執行結果是 。
s = "bb c"
print string.split(3 * s)
6. 、 、 是科技創新的三大支柱。
7.無窮循環while True:的循環體中可用 語句退出循環。
三.閱讀程序並回答問題(每題5分,共40分)
1.當輸入是54321時,寫出下面程序的執行結果。
def main():
num = input(「請輸入一個整數:」)
while num != 0:
print num % 10
num = num / 10
main()
答案: 5 4 3 2 1 |
2.寫出下面程序的執行結果。
a = [1, 20, 32, 14, 5, 62, 78, 38, 9, 10]
for i in range(9):
if( a[i] > a[i+1] ):
a[i], a[i+1] = a[i+1], a[i]
print a
3.寫出下面程序的執行結果。
def main():
lst = [2, 4, 6, 8, 10]
lst = 2 * lst
lst[1], lst[3] = lst[3], lst[1]
swap(lst, 2, 4)
for i in range(len(lst) - 4):
print lst[i], " "
def swap(lists, ind1, ind2):
lists[ind1], lists[ind2] = lists[ind2], lists[ind1]
main()
4.寫出下面程序的執行結果。
import string
def main():
s = "I like python!"
s = string.lower(s)
alist = []
countlist = []
count=0
for i in range( len(s) ):
if (ord(s[i]) <= ord('Z') and ord(s[i]) >= ord('A')) \
or (ord(s[i]) <= ord('z') and ord(s[i]) >= ord('a')):
if (s[i] in alist):
sign = alist.index(s[i])
countlist[sign] += 1
else:
alist.append(s[i])
countlist.append(1)
count += 1
for i in range(count):
print alist[i], " ", countlist[i]
main()
1.list 方法
1、建立一個列表
只要把逗號分隔的不一樣的數據項使用方括號括起來便可。以下所示:
複製代碼代碼以下:
list1 = ['physics', 'chemistry', 1997, 2000];
list2 = [1, 2, 3, 4, 5 ];
list3 = ["a", "b", "c", "d"];
與字符串的索引同樣,列表索引從0開始。列表能夠進行截取、組合等。
2、訪問列表中的值
使用下標索引來訪問列表中的值,一樣你也能夠使用方括號的形式截取字符,以下所示:
複製代碼代碼以下:
#!/usr/bin/python
list1 = ['physics', 'chemistry', 1997, 2000];
list2 = [1, 2, 3, 4, 5, 6, 7 ];
print "list1[0]: ", list1[0]
print "list2[1:5]: ", list2[1:5]
以上實例輸出結果:
複製代碼代碼以下:
list1[0]: physics
list2[1:5]: [2, 3, 4, 5]
3、更新列表
你能夠對列表的數據項進行修改或更新,你也能夠使用append()方法來添加列表項,以下所示:
複製代碼代碼以下:
#!/usr/bin/python
list = ['physics', 'chemistry', 1997, 2000];
print "Value available at index 2 : "
print list[2];
list[2] = 2001;
print "New value available at index 2 : "
print list[2];
以上實例輸出結果:
複製代碼代碼以下:
Value available at index 2 :
1997
New value available at index 2 :
2001
4、刪除列表元素
能夠使用 del 語句來刪除列表的的元素,以下實例:
複製代碼代碼以下:
#!/usr/bin/python
list1 = ['physics', 'chemistry', 1997, 2000];
print list1;
del list1[2];
print "After deleting value at index 2 : "
print list1;
以上實例輸出結果:
複製代碼代碼以下:
['physics', 'chemistry', 1997, 2000]
After deleting value at index 2 :
['physics', 'chemistry', 2000]
5、Python列表腳本操做符
列表對 + 和 * 的操做符與字符串類似。+ 號用於組合列表,* 號用於重複列表。
以下所示:
Python 表達式 |
結果 |
描述 |
len([1, 2, 3]) |
3 |
長度 |
[1, 2, 3] + [4, 5, 6] |
[1, 2, 3, 4, 5, 6] |
組合 |
['Hi!'] * 4 |
['Hi!', 'Hi!', 'Hi!', 'Hi!'] |
重複 |
3 in [1, 2, 3] |
True |
元素是否存在於列表中 |
for x in [1, 2, 3]: print x, |
1 2 3 |
迭代 |
6、Python列表截取
Python的列表截取與字符串操做類型,以下所示:
複製代碼代碼以下:
L = ['spam', 'Spam', 'SPAM!']
操做:
Python 表達式 |
結果 |
描述 |
L[2] |
'SPAM!' |
讀取列表中第三個元素 |
L[-2] |
'Spam' |
讀取列表中倒數第二個元素 |
L[1:] |
['Spam', 'SPAM!'] |
從第二個元素開始截取列表 |
7、Python列表操做的函數和方法
列表操做包含如下函數:
一、cmp(list1, list2):比較兩個列表的元素
二、len(list):列表元素個數
三、max(list):返回列表元素最大值
四、min(list):返回列表元素最小值
五、list(seq):將元組轉換爲列表
列表操做包含如下方法:
一、list.append(obj):在列表末尾添加新的對象
二、list.count(obj):統計某個元素在列表中出現的次數
三、list.extend(seq):在列表末尾一次性追加另外一個序列中的多個值(用新列表擴展原來的列表)
四、list.index(obj):從列表中找出某個值第一個匹配項的索引位置
五、list.insert(index, obj):將對象插入列表
六、list.pop(obj=list[-1]):移除列表中的一個元素(默認最後一個元素),而且返回該元素的值
七、list.remove(obj):移除列表中某個值的第一個匹配項
八、list.reverse():反向列表中元素
九、list.sort([func]):對原列表進行排序
字典
1、什麼是字典?
字典是Python語言中惟一的映射類型。
映射類型對象裏哈希值(鍵,key)和指向的對象(值,value)是一對多的的關係,一般被認爲是可變的哈希表。
字典對象是可變的,它是一個容器類型,能存儲任意個數的Python對象,其中也可包括其餘容器類型。
字典類型與序列類型的區別:
1.存取和訪問數據的方式不一樣。
2.序列類型只用數字類型的鍵(從序列的開始按數值順序索引);
3.映射類型能夠用其餘對象類型做鍵(如:數字、字符串、元祖,通常用字符串做鍵),和序列類型的鍵不一樣,映射類型的鍵直4.接或間接地和存儲數據值相關聯。
5.映射類型中的數據是無序排列的。這和序列類型是不同的,序列類型是以數值序排列的。
6.映射類型用鍵直接「映射」到值。
字典是Python中最強大的數據類型之一。
2、如何建立字典和給字典賦值
簡單地說字典就是用大括號包裹的鍵值對的集合。(鍵值對也被稱做項)
通常形式:
複製代碼代碼以下:
adict = {}
adict = {key1:value2, key2:value2, …}
或用dict()函數,如,adict = dict() 或 adict = dict((['x',1],['y',2]))這樣寫對嗎?adict = dict(['x',1],['y',2])。關鍵字參數建立字典,如:adict= dict(name='allen',age='40′)
或用fromkeys()方法,如,adict = {}.fromkeys((‘x','y'), -1) 這樣建立的字典的value是同樣的,若不給值,默認爲None。
特色:
一、鍵與值用冒號「:」分開;
二、項與項用逗號「,」分開;
三、字典中的鍵必須是惟一的,而值能夠不惟一。
複製代碼代碼以下:
adict = {‘name':'allen', ‘name':'lucy', ‘age':'40′} 與 bdict = {‘name':'allen', ‘name2′:'allen', ‘age':'40′}
注意:若是字典中的值爲數字,最好使用字符串數字形式,如:'age':'040′ 而不用 ‘age':040
3、字典的基本操做
一、如何訪問字典中的值?
adict[key] 形式返回鍵key對應的值value,若是key不在字典中會引起一個KeyError。
二、如何檢查key是否在字典中?
a、has_key()方法 形如:adict.haskey(‘name') 有–>True,無–>False
b、in 、not in 形如:'name' in adict 有–>True,無–>False
三、如何更新字典?
a、添加一個數據項(新元素)或鍵值對
adict[new_key] = value 形式添加一個項
b、更新一個數據項(元素)或鍵值對
adict[old_key] = new_value
c、刪除一個數據項(元素)或鍵值對
del adict[key] 刪除鍵key的項 / del adict 刪除整個字典
adict.pop(key) 刪除鍵key的項並返回key對應的 value值
4、映射類型操做符
標準類型操做符(+,-,*,<,>,<=,>=,==,!=,and,or, not)
a、字典不支持拼接和重複操做符(+,*)
b、字典的比較操做
先比較字典的長度也就是字典的元素個數
鍵比較
值比較
例子:
複製代碼代碼以下:
adict = {}
bdict = {‘name':'allen', ‘age':'40′}
cmp(adict, bdict) < –>-1 or > –>1 or == –>0
5、映射相關的函數
一、len() 返回字典的長度
二、hash() 返回對象的哈希值,能夠用來判斷一個對象可否用來做爲字典的鍵
三、dict() 工廠函數,用來建立字典
6、字典的方法
一、adict.keys() 返回一個包含字典全部KEY的列表;
二、adict.values() 返回一個包含字典全部value的列表;
三、adict.items() 返回一個包含全部(鍵,值)元祖的列表;
四、adict.clear() 刪除字典中的全部項或元素;
五、adict.copy() 返回一個字典淺拷貝的副本;
六、adict.fromkeys(seq, val=None) 建立並返回一個新字典,以seq中的元素作該字典的鍵,val作該字典中全部鍵對應的初始值(默認爲None);
七、adict.get(key, default = None) 返回字典中key對應的值,若key不存在字典中,則返回default的值(default默認爲None);
八、adict.has_key(key) 若是key在字典中,返回True,不然返回False。 如今用 in 、 not in;
九、adict.iteritems()、adict.iterkeys()、adict.itervalues() 與它們對應的非迭代方法同樣,不一樣的是它們返回一個迭代子,而不是一個列表;
十、adict.pop(key[,default]) 和get方法類似。若是字典中存在key,刪除並返回key對應的vuale;若是key不存在,且沒有給出default的值,則引起keyerror異常;
十一、adict.setdefault(key, default=None) 和set()方法類似,但若是字典中不存在Key鍵,由 adict[key] = default 爲它賦值;
十二、adict.update(bdict) 將字典bdict的鍵值對添加到字典adict中。
7、字典的遍歷
一、遍歷字典的key(鍵)
複製代碼代碼以下:
for key in adict.keys():print key
二、遍歷字典的value(值)
複製代碼代碼以下:
for value in adict.values(): print value
三、遍歷字典的項(元素)
複製代碼代碼以下:
for item in adict.items():print item
四、遍歷字典的key-value
複製代碼代碼以下:
for item,value in adict.items(): print ‘key=%s, value=%s' %(item, value) 或 for item,value in adict.iteritems(): print ‘key=%s, value=%s' %(item, value)
集合
set 是一個無序的元素集合,支持並、交、差及對稱差等數學運算, 但因爲 set 不記錄元素位置,所以不支持索引、分片等類序列的操做。
初始化
複製代碼代碼以下:
s0 = set()
d0 = {}
s1 = {0}
s2 = {i % 2 for i in range(10)}
s = set('hi')
t = set(['h', 'e', 'l', 'l', 'o'])
print(s0, s1, s2, s, t, type(d0))
運行結果:
複製代碼代碼以下:
set() {0} {0, 1} {'i', 'h'} {'e', 'o', 'l', 'h'} <class 'dict'>
提示
1.s0、d0:使用 {} 只能建立空字典,建立空集必須用 set();
2.ss、sl:set 中的元素是 無序不重複 的,能夠利用這個特色去除列表中的重複元素。
運算操做
複製代碼代碼以下:
print(s.intersection(t), s & t) # 交集
print(s.union(t), s | t) # 並集
print(s.difference(t), s - t) # 差集
print(s.symmetric_difference(t), s ^ t) # 對稱差集
print(s1.issubset(s2), s1 <= s2) # 子集
print(s1.issuperset(s2), s1 >= s2) # 包含
運行結果:
複製代碼代碼以下:
{'h'} {'h'}
{'l', 'h', 'i', 'o', 'e'} {'l', 'h', 'i', 'o', 'e'}
{'i'} {'i'}
{'i', 'l', 'o', 'e'} {'i', 'l', 'o', 'e'}
True True
False False
提示
1.非運算符的方法接受任何可迭代對象做爲參數,如 s.update([0, 1]);
2.其餘等價操做:s.update(t) 與 s |= t,s.intersection_update(t) 與 s &= t,s.difference_update(t) 與 s -= t,s.symmetric_difference_update(t) 與 s ^= t 等。
基本方法
複製代碼代碼以下:
s = {0}
print(s, len(s)) # 獲取集合中的元素的總數
s.add("x") # 添加一個元素
print(s)
s.update([1,2,3]) # 添加多個元素
print(s, "x" in s) # 成員資格測試
s.remove("x") # 去掉一個元素
print(s, "x" not in s)
s.discard("x") # 若是集合存在指定元素,則刪除該元素
c = s.copy() # 複製集合
print(s, s.pop()) # 彈出集合中的一個不肯定元素,若是原集合爲空則引起 KeyError
s.clear() # 刪除集合中的元素
print(s, c)
運行結果:
複製代碼代碼以下:
{0} 1
{0, 'x'}
{0, 'x', 1, 2, 3} True
{0, 1, 2, 3} True
{1, 2, 3} 0
set() {0, 1, 2, 3}
Str字符串方法
1、去空格及特殊符號
複製代碼代碼以下:
s.strip().lstrip().rstrip(',')
2、複製字符串
複製代碼代碼以下:
#strcpy(sStr1,sStr2)
sStr1 = 'strcpy'
sStr2 = sStr1
sStr1 = 'strcpy2'
print sStr2
3、鏈接字符串
複製代碼代碼以下:
#strcat(sStr1,sStr2)
sStr1 = 'strcat'
sStr2 = 'append'
sStr1 += sStr2
print sStr1
4、查找字符
複製代碼代碼以下:
#strchr(sStr1,sStr2)
# < 0 爲未找到
sStr1 = 'strchr'
sStr2 = 's'
nPos = sStr1.index(sStr2)
print nPos
5、比較字符串
複製代碼代碼以下:
#strcmp(sStr1,sStr2)
sStr1 = 'strchr'
sStr2 = 'strch'
print cmp(sStr1,sStr2)
6、掃描字符串是否包含指定的字符
複製代碼代碼以下:
#strspn(sStr1,sStr2)
sStr1 = '12345678'
sStr2 = '456'
#sStr1 and chars both in sStr1 and sStr2
print len(sStr1 and sStr2)
7、字符串長度
複製代碼代碼以下:
#strlen(sStr1)
sStr1 = 'strlen'
print len(sStr1)
8、將字符串中的大小寫轉換
複製代碼代碼以下:
S.lower() #小寫
S.upper() #大寫
S.swapcase() #大小寫互換
S.capitalize() #首字母大寫
String.capwords(S) #這是模塊中的方法。它把S用split()函數分開,而後用capitalize()把首字母變成大寫,最後用join()合併到一塊兒
#實例:
#strlwr(sStr1)
sStr1 = 'JCstrlwr'
sStr1 = sStr1.upper()
#sStr1 = sStr1.lower()
print sStr1
9、追加指定長度的字符串
複製代碼代碼以下:
#strncat(sStr1,sStr2,n)
sStr1 = '12345'
sStr2 = 'abcdef'
n = 3
sStr1 += sStr2[0:n]
print sStr1
10、字符串指定長度比較
複製代碼代碼以下:
#strncmp(sStr1,sStr2,n)
sStr1 = '12345'
sStr2 = '123bc'
n = 3
print cmp(sStr1[0:n],sStr2[0:n])
11、複製指定長度的字符
複製代碼代碼以下:
#strncpy(sStr1,sStr2,n)
sStr1 = ''
sStr2 = '12345'
n = 3
sStr1 = sStr2[0:n]
print sStr1
12、將字符串前n個字符替換爲指定的字符
複製代碼代碼以下:
#strnset(sStr1,ch,n)
sStr1 = '12345'
ch = 'r'
n = 3
sStr1 = n * ch + sStr1[3:]
print sStr1
13、掃描字符串
複製代碼代碼以下:
#strpbrk(sStr1,sStr2)
sStr1 = 'cekjgdklab'
sStr2 = 'gka'
nPos = -1
for c in sStr1:
if c in sStr2:
nPos = sStr1.index(c)
break
print nPos
14、翻轉字符串
複製代碼代碼以下:
#strrev(sStr1)
sStr1 = 'abcdefg'
sStr1 = sStr1[::-1]
print sStr1
15、查找字符串
複製代碼代碼以下:
#strstr(sStr1,sStr2)
sStr1 = 'abcdefg'
sStr2 = 'cde'
print sStr1.find(sStr2)
16、分割字符串
複製代碼代碼以下:
#strtok(sStr1,sStr2)
sStr1 = 'ab,cde,fgh,ijk'
sStr2 = ','
sStr1 = sStr1[sStr1.find(sStr2) + 1:]
print sStr1
#或者
s = 'ab,cde,fgh,ijk'
print(s.split(','))
17、鏈接字符串
複製代碼代碼以下:
delimiter = ','
mylist = ['Brazil', 'Russia', 'India', 'China']
print delimiter.join(mylist)
18、PHP 中 addslashes 的實現
複製代碼代碼以下:
def addslashes(s):
d = {'"':'\\"', "'":"\\'", "\0":"\\\0", "\\":"\\\\"}
return ''.join(d.get(c, c) for c in s)
s = "John 'Johny' Doe (a.k.a. \"Super Joe\")\\\0"
print s
print addslashes(s)
19、只顯示字母與數字
複製代碼代碼以下:
def OnlyCharNum(s,oth=''):
s2 = s.lower();
fomart = 'abcdefghijklmnopqrstuvwxyz0123456789'
for c in s2:
if not c in fomart:
s = s.replace(c,'');
return s;
print(OnlyStr("a000 aa-b"))
20、截取字符串
複製代碼代碼以下:
str = '0123456789′
print str[0:3] #截取第一位到第三位的字符
print str[:] #截取字符串的所有字符
print str[6:] #截取第七個字符到結尾
print str[:-3] #截取從頭開始到倒數第三個字符以前
print str[2] #截取第三個字符
print str[-1] #截取倒數第一個字符
print str[::-1] #創造一個與原字符串順序相反的字符串
print str[-3:-1] #截取倒數第三位與倒數第一位以前的字符
print str[-3:] #截取倒數第三位到結尾
print str[:-5:-3] #逆序截取,具體啥意思沒搞明白?
21、字符串在輸出時的對齊
複製代碼代碼以下:
S.ljust(width,[fillchar])
#輸出width個字符,S左對齊,不足部分用fillchar填充,默認的爲空格。
S.rjust(width,[fillchar]) #右對齊
S.center(width, [fillchar]) #中間對齊
S.zfill(width) #把S變成width長,並在右對齊,不足部分用0補足
22、字符串中的搜索和替換
複製代碼代碼以下:
S.find(substr, [start, [end]])
#返回S中出現substr的第一個字母的標號,若是S中沒有substr則返回-1。start和end做用就至關於在S[start:end]中搜索
S.index(substr, [start, [end]])
#與find()相同,只是在S中沒有substr時,會返回一個運行時錯誤
S.rfind(substr, [start, [end]])
#返回S中最後出現的substr的第一個字母的標號,若是S中沒有substr則返回-1,也就是說從右邊算起的第一次出現的substr的首字母標號
S.rindex(substr, [start, [end]])
S.count(substr, [start, [end]]) #計算substr在S中出現的次數
S.replace(oldstr, newstr, [count])
#把S中的oldstar替換爲newstr,count爲替換次數。這是替換的通用形式,還有一些函數進行特殊字符的替換
S.strip([chars])
#把S中先後chars中有的字符所有去掉,能夠理解爲把S先後chars替換爲None
S.lstrip([chars])
S.rstrip([chars])
S.expandtabs([tabsize])
#把S中的tab字符替換沒空格,每一個tab替換爲tabsize個空格,默認是8個
23、字符串的分割和組合
複製代碼代碼以下:
S.split([sep, [maxsplit]])
#以sep爲分隔符,把S分紅一個list。maxsplit表示分割的次數。默認的分割符爲空白字符
S.rsplit([sep, [maxsplit]])
S.splitlines([keepends])
#把S按照行分割符分爲一個list,keepends是一個bool值,若是爲真每行後而會保留行分割符。
S.join(seq) #把seq表明的序列──字符串序列,用S鏈接起來
24、字符串的mapping,這一功能包含兩個函數
複製代碼代碼以下:
String.maketrans(from, to)
#返回一個256個字符組成的翻譯表,其中from中的字符被一一對應地轉換成to,因此from和to必須是等長的。
S.translate(table[,deletechars])
# 使用上面的函數產後的翻譯表,把S進行翻譯,並把deletechars中有的字符刪掉。須要注意的是,若是S爲unicode字符串,那麼就不支持 deletechars參數,能夠使用把某個字符翻譯爲None的方式實現相同的功能。此外還能夠使用codecs模塊的功能來建立更加功能強大的翻譯表。
25、字符串還有一對編碼和解碼的函數
複製代碼代碼以下:
S.encode([encoding,[errors]])
# 其中encoding能夠有多種值,好比gb2312 gbk gb18030 bz2 zlib big5 bzse64等都支持。errors默認值爲"strict",意思是UnicodeError。可能的值還有'ignore', 'replace', 'xmlcharrefreplace', 'backslashreplace' 和全部的經過codecs.register_error註冊的值。這一部份內容涉及codecs模塊,不是特明白
S.decode([encoding,[errors]])
26、字符串的測試、判斷函數,這一類函數在string模塊中沒有,這些函數返回的都是bool值
複製代碼代碼以下:
S.startswith(prefix[,start[,end]])
#是否以prefix開頭
S.endswith(suffix[,start[,end]])
#以suffix結尾
S.isalnum()
#是否全是字母和數字,並至少有一個字符
S.isalpha() #是否全是字母,並至少有一個字符
S.isdigit() #是否全是數字,並至少有一個字符
S.isspace() #是否全是空白字符,並至少有一個字符
S.islower() #S中的字母是否全是小寫
S.isupper() #S中的字母是否即是大寫
S.istitle() #S是不是首字母大寫的
27、字符串類型轉換函數,這幾個函數只在string模塊中有
複製代碼代碼以下:
string.atoi(s[,base])
#base默認爲10,若是爲0,那麼s就能夠是012或0x23這種形式的字符串,若是是16那麼s就只能是0x23或0X12這種形式的字符串
string.atol(s[,base]) #轉成long
string.atof(s[,base]) #轉成float
tuple元組方法
1、建立元組
複製代碼代碼以下:
tup1 = ('physics', 'chemistry', 1997, 2000);
tup2 = (1, 2, 3, 4, 5 );
tup3 = "a", "b", "c", "d";
建立空元組
複製代碼代碼以下:
tup1 = ();
元組中只包含一個元素時,須要在元素後面添加逗號來消除歧義
複製代碼代碼以下:
tup1 = (50,);
元組與字符串相似,下標索引從0開始,能夠進行截取,組合等。
2、訪問元組
元組能夠使用下標索引來訪問元組中的值,以下實例:
複製代碼代碼以下:
#!/usr/bin/python
tup1 = ('physics', 'chemistry', 1997, 2000);
tup2 = (1, 2, 3, 4, 5, 6, 7 );
print "tup1[0]: ", tup1[0]
print "tup2[1:5]: ", tup2[1:5]
#以上實例輸出結果:
#tup1[0]: physics
#tup2[1:5]: [2, 3, 4, 5]
3、修改元組
元組中的元素值是不容許修改的,但咱們能夠對元組進行鏈接組合,以下實例:
複製代碼代碼以下:
#!/usr/bin/python
tup1 = (12, 34.56);
tup2 = ('abc', 'xyz');
# 如下修改元組元素操做是非法的。
# tup1[0] = 100;
# 建立一個新的元組
tup3 = tup1 + tup2;
print tup3;
#以上實例輸出結果:
#(12, 34.56, 'abc', 'xyz')
4、刪除元組
元組中的元素值是不容許刪除的,但咱們能夠使用del語句來刪除整個元組,以下實例:
複製代碼代碼以下:
#!/usr/bin/python
tup = ('physics', 'chemistry', 1997, 2000);
print tup;
del tup;
print "After deleting tup : "
print tup;
#以上實例元組被刪除後,輸出變量會有異常信息,輸出以下所示:
#('physics', 'chemistry', 1997, 2000)
#After deleting tup :
#Traceback (most recent call last):
# File "test.py", line 9, in <module>
# print tup;
#NameError: name 'tup' is not defined[/code]
5、元組運算符
與字符串同樣,元組之間能夠使用 + 號和 * 號進行運算。這就意味着他們能夠組合和複製,運算後會生成一個新的元組。
6、元組索引,截取
由於元組也是一個序列,因此咱們能夠訪問元組中的指定位置的元素,也能夠截取索引中的一段元素,以下所示:
元組:
複製代碼代碼以下:
L = ('spam', 'Spam', 'SPAM!')
7、無關閉分隔符
任意無符號的對象,以逗號隔開,默認爲元組,以下實例:
複製代碼代碼以下:
#!/usr/bin/python
print 'abc', -4.24e93, 18+6.6j, 'xyz';
x, y = 1, 2;
print "Value of x , y : ", x,y;
以上實例容許結果:
複製代碼代碼以下:
abc -4.24e+93 (18+6.6j) xyz
Value of x , y : 1 2
8、元組內置函數
Python元組包含了如下內置函數
一、cmp(tuple1, tuple2):比較兩個元組元素。
二、len(tuple):計算元組元素個數。
三、max(tuple):返回元組中元素最大值。
四、min(tuple):返回元組中元素最小值。
五、tuple(seq):將列表轉換爲元組。
9、另外一種解讀
tuple和list很是相似,可是tuple一旦初始化就不能修改,好比一樣是列出同窗的名字:
複製代碼代碼以下:
>>> classmates = ('Michael', 'Bob', 'Tracy')
如今,classmates這個tuple不能變了,它也沒有append(),insert()這樣的方法。其餘獲取元素的方法和list是同樣的,你能夠正常地使用classmates[0],classmates[-1],但不能賦值成另外的元素。
不可變的tuple有什麼意義?由於tuple不可變,因此代碼更安全。若是可能,能用tuple代替list就儘可能用tuple。
tuple的陷阱:當你定義一個tuple時,在定義的時候,tuple的元素就必須被肯定下來,好比:
複製代碼代碼以下:
>>> t = (1, 2)
>>> t
(1, 2)
若是要定義一個空的tuple,能夠寫成():
複製代碼代碼以下:
>>> t = ()
>>> t
()
可是,要定義一個只有1個元素的tuple,若是你這麼定義:
複製代碼代碼以下:
>>> t = (1)
>>> t
1
定義的不是tuple,是1這個數!這是由於括號()既能夠表示tuple,又能夠表示數學公式中的小括號,這就產生了歧義,所以,Python規定,這種狀況下,按小括號進行計算,計算結果天然是1。
因此,只有1個元素的tuple定義時必須加一個逗號,,來消除歧義:
複製代碼代碼以下:
>>> t = (1,)
>>> t
(1,)
Python在顯示只有1個元素的tuple時,也會加一個逗號,,以避免你誤解成數學計算意義上的括號。
在來看一個「可變的」tuple:
複製代碼代碼以下:
>>> t = ('a', 'b', ['A', 'B'])
>>> t[2][0] = 'X'
>>> t[2][1] = 'Y'
>>> t
('a', 'b', ['X', 'Y'])
這個tuple定義的時候有3個元素,分別是'a','b'和一個list。不是說tuple一旦定義後就不可變了嗎?怎麼後來又變了?
別急,咱們先看看定義的時候tuple包含的3個元素: 當咱們把list的元素'A'和'B'修改成'X'和'Y'後,tuple變爲: 表面上看,tuple的元素確實變了,但其實變的不是tuple的元素,而是list的元素。tuple一開始指向的list並無改爲別的list,因此,tuple所謂的「不變」是說,tuple的每一個元素,指向永遠不變。即指向'a',就不能改爲指向'b',指向一個list,就不能改爲指向其餘對象,但指向的這個list自己是可變的!理解了「指向不變」後,要建立一個內容也不變的tuple怎麼作?那就必須保證tuple的每個元素自己也不能變。