㈠ 小猿圈python之python期末考試測試題(一)
又快臨近期末考試了,小夥伴們是不是又開始焦慮了呢?掛科怎麼辦?如果很幸運看到我的文章,你就偷著樂吧,我總結出:一般python期末考試老師們最愛考的內容,一定要好好看啊,爭取做到python不掛科;還有暑假馬上來了,小夥伴們可以在閑暇之際,看看小猿圈的視頻,為以後找工作墊墊基礎,也是很不錯的。
一、選擇題
1、已知x=[1,2]和y=[3,4],那麼x+y等於什麼( )
A、3 B、7 C、[1,2,3,4] D、[4,6]
2、os.path模塊的下列方法,哪個是用來判斷指定路徑是否存在的?( )
A、exists() B、exist() C、getsize() D、isfile()
3、以下選項中不是 Python 對文件的寫操作方法的是 ( D )
A、 writelines B、write C、rite 和 seek D、writetext
4、關於演算法的描述,以下選項中錯誤的是 ( B )
A、演算法是指解題方案的准確而完整的描述
B、演算法的復雜度主要包括時間復雜度和數據復雜度
C、演算法具有可行性、確定性、有窮性的基本特徵
D、演算法的基本要素包括數據對象的運算和操作及演算法的控制結構
解釋:演算法復雜度是指演算法在編寫成可執行程序後,運行時所需要的資源,資源包括時間資源和內存資源。
5、.關於Python的lambda函數,以下選項中描述錯誤的是 ( B )
A、 lambda函數將函數名作為函數結果返回
B、f = lambda x,y:x+y 執行後,f的類型為數字類型
C、lambda用於定義簡單的、能夠在一行內表示的函數
D、可以使用lambda函數定義列表的排序原則
6、基本的Python內置函數eval(x)的作用是 ( B )
A、 將x轉換成浮點數
B、去掉字元串x最外側引號,當作Python表達式評估返回其值
C、計算字元串x作為Python語句的值
D、 將整數x轉換為十六進制字元串
二、填空題
1、 在Python中____表示空類型。(None)
2、 查看變數類型的Python內置函數是______。(type())
3、list(map(str, [1, 2, 3]))的執行結果為___________。([『1』, 『2』, 『3』])
4、 Python標准庫math中用來計算平方根的函數是____。(sqrt)
5、 假設有列表a = [『name』, 『age』, 『sex』]和b = [『Dong』, 38, 『Male』],請使用一個語句將這兩個列表的內容轉換為字典,並且以列表a中的元素為「鍵」,以列表b中的元素為「值」,這個語句可以寫為___________。(c = dict(zip(a, b)))
三、簡答題
1、簡單解釋Python基於值的自動內存管理方式?
----Python採用的是基於值得內存管理方式,在Python中可以為不同變數賦值為相同值,這個值在內存中只有一份,多個變數指向同一個內存地址;Python具有自動內存管理功能,會自動跟蹤內存中所有的值,對於沒有任何變數指向的值,Python自動將其刪除。
2、異常和錯誤有什麼區別?
----異常是指因為程序執行過程中出錯而在正常控制流以外採取的行為。嚴格來說,語法錯誤和邏輯錯誤不屬於異常,但有些語法錯誤往往會導致異常,例如由於大小寫拼寫錯誤而訪問不存在的對象,或者試圖訪問不存在的文件,等等。
3、請用自己的演算法, 按升序合並如下兩個list, 並去除重復的元素:
list1 = [2, 3, 7, 4, 9, 5, 6,18]
list2 = [5, 6, 10, 17, 3, 2,1]
----先轉換成集合自動去重,再轉換成列表
list1=[2, 3, 7, 4, 9, 5, 6,18]
list2=[5, 6, 10, 17, 3, 2,1]
list3=list(set(list1+list2))
4、求結果
def num():
return [lambda x: i*x for i in range(4)]
print([m(2) for m in num()])
答案:[6, 6, 6, 6]
5、如何生成一個隨機數?
import random
def rdm(n):
lis = []
for i in range(n):
n = random.randint(1,9)
lis.append(str(n))
s = ''.join(lis)
return int(s)
這套題就到這里,同學們做的怎麼樣啊,如果是毫無壓力,那估計你這個學期學的python還闊以了,如果有點難度,那就要仔細看看了,因為這套題很基礎,看哪沒有學明白,好好看看那一部分的內容,自己復習不進去,也可以來小猿圈看看,把自己的弱項重新聽聽課,准備迎接期末考試吧,希望大家考的都會,蒙的全對,加油啦!
㈡ python如何判斷self.屬性是否存在
有關這個問題 有三種解決辦法:
方法一:這就要使用一個函數:hasattr(object,name)
下面看下函數hasattr()的用法:
代碼含義:通過異常捕捉來實現邏輯!
㈢ Python 有什麼奇技淫巧
Python奇技淫巧
當發布python第三方package時, 並不希望代碼中所有的函數或者class可以被外部import, 在 __init__.py 中添加 __all__ 屬性,
該list中填寫可以import的類或者函數名, 可以起到限制的import的作用, 防止外部import其他函數或者類
#!/usr/bin/env python
# -*- coding: utf-8 -*-
frombaseimportAPIBase
fromclientimportClient
fromdecoratorimportinterface, export, stream
fromserverimportServer
fromstorageimportStorage
fromutilimport(LogFormatter, disable_logging_to_stderr,
enable_logging_to_kids, info)
__all__ = ['APIBase','Client','LogFormatter','Server',
'Storage','disable_logging_to_stderr','enable_logging_to_kids',
'export','info','interface','stream']
with的魔力
with語句需要支持 上下文管理協議的對象 , 上下文管理協議包含 __enter__ 和 __exit__ 兩個方法. with語句建立運行時上下文需要通過這兩個方法執行 進入和退出 操作.
其中 上下文表達式 是跟在with之後的表達式, 該表示大返回一個上下文管理對象
# 常見with使用場景
withopen("test.txt","r")asmy_file:# 注意, 是__enter__()方法的返回值賦值給了my_file,
forlineinmy_file:
print line
詳細原理可以查看這篇文章, 淺談 Python 的 with 語句
知道具體原理, 我們可以自定義支持上下文管理協議的類, 類中實現 __enter__ 和 __exit__ 方法
#!/usr/bin/env python
# -*- coding: utf-8 -*-
classMyWith(object):
def__init__(self):
print"__init__ method"
def__enter__(self):
print"__enter__ method"
returnself# 返回對象給as後的變數
def__exit__(self, exc_type, exc_value, exc_traceback):
print"__exit__ method"
ifexc_tracebackisNone:
print"Exited without Exception"
returnTrue
else:
print"Exited with Exception"
returnFalse
deftest_with():
withMyWith()asmy_with:
print"running my_with"
print"------分割線-----"
withMyWith()asmy_with:
print"running before Exception"
raiseException
print"running after Exception"
if__name__ =='__main__':
test_with()
執行結果如下:
__init__ method
__enter__ method
running my_with
__exit__ method
ExitedwithoutException
------分割線-----
__init__ method
__enter__ method
running before Exception
__exit__ method
ExitedwithException
Traceback(most recent call last):
File"bin/python", line34,in<mole>
exec(compile(__file__f.read(), __file__, "exec"))
File"test_with.py", line33,in<mole>
test_with()
File"test_with.py", line28,intest_with
raiseException
Exception
證明了會先執行 __enter__ 方法, 然後調用with內的邏輯, 最後執行 __exit__ 做退出處理, 並且, 即使出現異常也能正常退出
filter的用法
相對 filter 而言, map和rece使用的會更頻繁一些, filter 正如其名字, 按照某種規則 過濾 掉一些元素
#!/usr/bin/env python
# -*- coding: utf-8 -*-
lst = [1,2,3,4,5,6]
# 所有奇數都會返回True, 偶數會返回False被過濾掉
print filter(lambda x: x % 2!=0, lst)
#輸出結果
[1,3,5]
一行作判斷
當條件滿足時, 返回的為等號後面的變數, 否則返回else後語句
lst = [1,2,3]
new_lst = lst[0]iflstisnotNoneelseNone
printnew_lst
# 列印結果
1
裝飾器之單例
使用裝飾器實現簡單的單例模式
# 單例裝飾器
defsingleton(cls):
instances = dict() # 初始為空
def_singleton(*args, **kwargs):
ifclsnotininstances:#如果不存在, 則創建並放入字典
instances[cls] = cls(*args, **kwargs)
returninstances[cls]
return_singleton
@singleton
classTest(object):
pass
if__name__ =='__main__':
t1 = Test()
t2 = Test()
# 兩者具有相同的地址
printt1, t2
staticmethod裝飾器
類中兩種常用的裝飾, 首先區分一下他們
普通成員函數, 其中第一個隱式參數為 對象
classmethod裝飾器 , 類方法(給人感覺非常類似於OC中的類方法), 其中第一個隱式參數為 類
staticmethod裝飾器 , 沒有任何隱式參數. python中的靜態方法類似與C++中的靜態方法
#!/usr/bin/env python
# -*- coding: utf-8 -*-
classA(object):
# 普通成員函數
deffoo(self, x):
print "executing foo(%s, %s)"% (self, x)
@classmethod# 使用classmethod進行裝飾
defclass_foo(cls, x):
print "executing class_foo(%s, %s)"% (cls, x)
@staticmethod# 使用staticmethod進行裝飾
defstatic_foo(x):
print "executing static_foo(%s)"% x
deftest_three_method():
obj = A()
# 直接調用噗通的成員方法
obj.foo("para")# 此處obj對象作為成員函數的隱式參數, 就是self
obj.class_foo("para")# 此處類作為隱式參數被傳入, 就是cls
A.class_foo("para")#更直接的類方法調用
obj.static_foo("para")# 靜態方法並沒有任何隱式參數, 但是要通過對象或者類進行調用
A.static_foo("para")
if__name__=='__main__':
test_three_method()
# 函數輸出
executing foo(<__main__.Aobject at0x100ba4e10>, para)
executing class_foo(<class'__main__.A'>,para)
executing class_foo(<class'__main__.A'>,para)
executing static_foo(para)
executing static_foo(para)
property裝飾器
定義私有類屬性
將 property 與裝飾器結合實現屬性私有化( 更簡單安全的實現get和set方法 )
#python內建函數
property(fget=None, fset=None, fdel=None, doc=None)
fget 是獲取屬性的值的函數, fset 是設置屬性值的函數, fdel 是刪除屬性的函數, doc 是一個字元串(like a comment).從實現來看,這些參數都是可選的
property有三個方法 getter() , setter() 和 delete() 來指定fget, fset和fdel。 這表示以下這行
classStudent(object):
@property #相當於property.getter(score) 或者property(score)
defscore(self):
returnself._score
@score.setter #相當於score = property.setter(score)
defscore(self, value):
ifnotisinstance(value, int):
raiseValueError('score must be an integer!')
ifvalue <0orvalue >100:
raiseValueError('score must between 0 ~ 100!')
self._score = value
iter魔法
通過yield和 __iter__ 的結合, 我們可以把一個對象變成可迭代的
通過 __str__ 的重寫, 可以直接通過想要的形式列印對象
#!/usr/bin/env python
# -*- coding: utf-8 -*-
classTestIter(object):
def__init__(self):
self.lst = [1,2,3,4,5]
defread(self):
foreleinxrange(len(self.lst)):
yieldele
def__iter__(self):
returnself.read()
def__str__(self):
return','.join(map(str, self.lst))
__repr__ = __str__
deftest_iter():
obj = TestIter()
fornuminobj:
printnum
printobj
if__name__ =='__main__':
test_iter()
神奇partial
partial使用上很像C++中仿函數(函數對象).
在stackoverflow給出了類似與partial的運行方式
defpartial(func, *part_args):
defwrapper(*extra_args):
args = list(part_args)
args.extend(extra_args)
returnfunc(*args)
returnwrapper
利用用閉包的特性綁定預先綁定一些函數參數, 返回一個可調用的變數, 直到真正的調用執行
#!/usr/bin/env python
# -*- coding: utf-8 -*-
fromfunctoolsimportpartial
defsum(a, b):
returna + b
deftest_partial():
fun = partial(sum, 2)# 事先綁定一個參數, fun成為一個只需要一個參數的可調用變數
printfun(3)# 實現執行的即是sum(2, 3)
if__name__ =='__main__':
test_partial()
# 執行結果
5
神秘eval
eval我理解為一種內嵌的python解釋器(這種解釋可能會有偏差), 會解釋字元串為對應的代碼並執行, 並且將執行結果返回
看一下下面這個例子
#!/usr/bin/env python
# -*- coding: utf-8 -*-
deftest_first():
return3
deftest_second(num):
returnnum
action = { # 可以看做是一個sandbox
"para":5,
"test_first": test_first,
"test_second": test_second
}
deftest_eavl():
condition = "para == 5 and test_second(test_first) > 5"
res = eval(condition, action) # 解釋condition並根據action對應的動作執行
printres
if__name__ =='_
exec
exec在Python中會忽略返回值, 總是返回None, eval會返回執行代碼或語句的返回值
exec 和 eval 在執行代碼時, 除了返回值其他行為都相同
在傳入字元串時, 會使用 compile(source, '<string>', mode) 編譯位元組碼. mode的取值為 exec 和 eval
#!/usr/bin/env python
# -*- coding: utf-8 -*-
deftest_first():
print"hello"
deftest_second():
test_first()
print"second"
deftest_third():
print"third"
action = {
"test_second": test_second,
"test_third": test_third
}
deftest_exec():
exec"test_second"inaction
if__name__ =='__main__':
test_exec() # 無法看到執行結果
getattr
getattr(object, name[, default]) Return the value of
the named attribute of object. name must be a string. If the string is
the name of one of the object』s attributes, the result is the value of
that attribute. For example, getattr(x, 『foobar』) is equivalent to
x.foobar. If the named attribute does not exist, default is returned if
provided, otherwise AttributeError is raised.
通過string類型的name, 返回對象的name屬性(方法)對應的值, 如果屬性不存在, 則返回默認值, 相當於object.name
# 使用範例
classTestGetAttr(object):
test = "test attribute"
defsay(self):
print"test method"
deftest_getattr():
my_test = TestGetAttr()
try:
printgetattr(my_test,"test")
exceptAttributeError:
print"Attribute Error!"
try:
getattr(my_test, "say")()
exceptAttributeError:# 沒有該屬性, 且沒有指定返回值的情況下
print"Method Error!"
if__name__ =='__main__':
test_getattr()
# 輸出結果
test attribute
test method
命令行處理
defprocess_command_line(argv):
"""
Return a 2-tuple: (settings object, args list).
`argv` is a list of arguments, or `None` for ``sys.argv[1:]``.
"""
ifargvisNone:
argv = sys.argv[1:]
# initialize the parser object:
parser = optparse.OptionParser(
formatter=optparse.TitledHelpFormatter(width=78),
add_help_option=None)
# define options here:
parser.add_option( # customized description; put --help last
'-h','--help', action='help',
help='Show this help message and exit.')
settings, args = parser.parse_args(argv)
# check number of arguments, verify values, etc.:
ifargs:
parser.error('program takes no command-line arguments; '
'"%s" ignored.'% (args,))
# further process settings & args if necessary
returnsettings, args
defmain(argv=None):
settings, args = process_command_line(argv)
# application code here, like:
# run(settings, args)
return0# success
if__name__ =='__main__':
status = main()
sys.exit(status)
讀寫csv文件
# 從csv中讀取文件, 基本和傳統文件讀取類似
importcsv
withopen('data.csv','rb')asf:
reader = csv.reader(f)
forrowinreader:
printrow
# 向csv文件寫入
importcsv
withopen('data.csv','wb')asf:
writer = csv.writer(f)
writer.writerow(['name','address','age'])# 單行寫入
data = [
( 'xiaoming ','china','10'),
( 'Lily','USA','12')]
writer.writerows(data) # 多行寫入
各種時間形式轉換
只發一張網上的圖, 然後差文檔就好了, 這個是記不住的
字元串格式化
一個非常好用, 很多人又不知道的功能
>>>name ="andrew"
>>>"my name is {name}".format(name=name)
'my name is andrew'
㈣ python模擬用戶登錄系統,如何兩個用戶輸入各自的密碼才能登入
users = {'root': ['123', False], 'westos': ['456', False]}
while True:
if all([x[1] for x in users.values()]):
print('two users login successfully')
break
user = input('input user name: ')
if not users.get(user):
print('unexist user')
continue
else:
for i in range(3):
pw = input('input password: ')
if users[user][0] == pw:
print(f'user `{user}` login successfully')
users[user][1] = True
break
用一個字典存儲username,pw以及登錄狀態. 10行判斷是否兩個人登錄狀態都為True,如果是,則列印並退出while. 否則13行輸入username,如果name不存在,while continue; 如果存在, 進入else,輸入密碼,密碼對則列印並修改狀態.超過3次退出for進入while.
㈤ Python中內置數據類型list,tuple,dict,set的區別和用法
這篇文章主要給大家介紹了Python中內置數據類型list,tuple,dict,set的區別和用法,都是非常基礎的知識,十分的細致全面,有需要的小夥伴可以參考下。
Python語言簡潔明了,可以用較少的代碼實現同樣的功能。這其中Python的四個內置數據類型功不可沒,他們即是list, tuple, dict, set。這里對他們進行一個簡明的總結。
List
字面意思就是一個集合,在Python中List中的元素用中括弧[]來表示,可以這樣定義一個List:
L = [12, 'China', 19.998]
可以看到並不要求元素的類型都是一樣的。當然也可以定義一個空的List:
L = []
Python中的List是有序的,所以要訪問List的話顯然要通過序號來訪問,就像是數組的下標一樣,一樣是下標從0開始:
>>> print L[0]
12
千萬不要越界,否則會報錯
>>> print L[3]
Traceback (most recent call last):
File "<stdin>", line 1, in <mole>
IndexError: list index out of range
List也可以倒序訪問,通過「倒數第x個」這樣的下標來表示序號,比如-1這個下標就表示倒數第一個元素:
>>> L = [12, 'China', 19.998]
>>> print L[-1]
19.998
-4的話顯然就越界了
>>> print L[-4]
Traceback (most recent call last):
File "<pyshell#2>", line 1, in <mole>
print L[-4]
IndexError: list index out of range
>>>
List通過內置的append()方法來添加到尾部,通過insert()方法添加到指定位置(下標從0開始):
>>> L = [12, 'China', 19.998]
>>> L.append('Jack')
>>> print L
[12, 'China', 19.998, 'Jack']
>>> L.insert(1, 3.14)
>>> print L
[12, 3.14, 'China', 19.998, 'Jack']
>>>
通過pop()刪除最後尾部元素,也可以指定一參數刪除指定位置:
>>> L.pop()
'Jack'
>>> print L
[12, 3.14, 'China', 19.998]
>>> L.pop(0)
12
>>> print L
[3.14, 'China', 19.998]
也可以通過下標進行復制替換
>>> L[1] = 'America'
>>> print L
[3.14, 'America', 19.998]
Tuple
Tuple可以看做是一種「不變」的List,訪問也是通過下標,用小括弧()表示:
>>> t = (3.14, 'China', 'Jason')
>>> print t
(3.14, 'China', 'Jason')
但是不能重新賦值替換:
>>> t[1] = 'America'
Traceback (most recent call last):
File "<pyshell#21>", line 1, in <mole>
t[1] = 'America'
TypeError: 'tuple' object does not support item assignment
也沒有pop和insert、append方法。
可以創建空元素的tuple:
t = ()
或者單元素tuple (比如加一個逗號防止和聲明一個整形歧義):
t = (3.14,)
那麼tuple這個類型到底有什麼用處呢?要知道如果你希望一個函數返回多個返回值,其實只要返回一個tuple就可以了,因為tuple裡面的含有多個值,而且是不可變的(就像是java裡面的final)。當然,tuple也是可變的,比如:
>>> t = (3.14, 'China', 'Jason', ['A', 'B'])
>>> print t
(3.14, 'China', 'Jason', ['A', 'B'])
>>> L = t[3]
>>> L[0] = 122
>>> L[1] = 233
>>> print t
(3.14, 'China', 'Jason', [122, 233])
這是因為Tuple所謂的不可變指的是指向的位置不可變,因為本例子中第四個元素並不是基本類型,而是一個List類型,所以t指向的該List的位置是不變的,但是List本身的內容是可以變化的,因為List本身在內存中的分配並不是連續的。
Dict
Dict是Python中非常重要的數據類型,就像它的字面意思一樣,它是個活字典,其實就是Key-Value鍵值對,類似於HashMap,可以用花括弧{}通過類似於定義一個C語言的結構體那樣去定義它:
>>> d = {
'Adam': 95,
'Lisa': 85,
'Bart': 59,
'Paul': 75
}
>>> print d
{'Lisa': 85, 'Paul': 75, 'Adam': 95, 'Bart': 59}
可以看到列印出來的結果都是Key:Value的格式,可以通過len函數計算它的長度(List,tuple也可以):
>>> len(d)
4
可以直接通過鍵值對方式添加dict中的元素:
>>> print d
{'Lisa': 85, 'Paul': 75, 'Adam': 95, 'Bart': 59}
>>> d['Jone'] = 99
>>> print d
{'Lisa': 85, 'Paul': 75, 'Adam': 95, 'Jone': 99, 'Bart': 59}
List和Tuple用下標來訪問內容,而Dict用Key來訪問: (字元串、整型、浮點型和元組tuple都可以作為dict的key)
>>> print d['Adam']
95
如果Key不存在,會報錯:
>>> print d['Jack']
Traceback (most recent call last):
File "<pyshell#40>", line 1, in <mole>
print d['Jack']
KeyError: 'Jack'
所以訪問之前最好先查詢下key是否存在:
>>> if 'Adam' in d : print 'exist key'
exist key
或者直接用保險的get方法:
>>> print d.get('Adam')
95
>>> print d.get('Jason')
None
至於遍歷一個dict,實際上是在遍歷它的所有的Key的集合,然後用這個Key來獲得對應的Value:
>>> for key in d : print key, ':', d.get(key)
Lisa : 85
Paul : 75
Adam : 95
Bart : 59
Dict具有一些特點:
查找速度快。無論是10個還是10萬個,速度都是一樣的,但是代價是耗費的內存大。List相反,佔用內存小,但是查找速度慢。這就好比是數組和鏈表的區別,數組並不知道要開辟多少空間,所以往往開始就會開辟一個大空間,但是直接通過下標查找速度快;而鏈表佔用的空間小,但是查找的時候必須順序的遍歷導致速度很慢
沒有順序。Dict是無順序的,而List是有序的集合,所以不能用Dict來存儲有序集合
Key不可變,Value可變。一旦一個鍵值對加入dict後,它對應的key就不能再變了,但是Value是可以變化的。所以List不可以當做Dict的Key,但是可以作為Value:
>>> print d
{'Lisa': 85, 'Paul': 75, 'Adam': 95, 'Jone': 99, 'Bart': 59}
>>> d['NewList'] = [12, 23, 'Jack']
>>> print d
{'Bart': 59, 'NewList': [12, 23, 'Jack'], 'Adam': 95, 'Jone': 99, 'Lisa': 85, 'Paul': 75}
Key不可重復。(下面例子中添加了一個'Jone':0,但是實際上原來已經有'Jone'這個Key了,所以僅僅是改了原來的value)
>>> print d
{'Bart': 59, 'NewList': [12, 23, 'Jack'], 'Adam': 95, 'Jone': 99, 'Lisa': 85, 'Paul': 75}
>>> d['Jone'] = 0
>>> print d
{'Bart': 59, 'NewList': [12, 23, 'Jack'], 'Adam': 95, 'Jone': 0, 'Lisa': 85, 'Paul': 75}
Dict的合並,如何將兩個Dict合並為一個,可以用dict函數:
>>> d1 = {'mike':12, 'jack':19}
>>> d2 = {'jone':22, 'ivy':17}
>>> dMerge = dict(d1.items() + d2.items())
>>> print dMerge
{'mike': 12, 'jack': 19, 'jone': 22, 'ivy': 17}
或者
>>> dMerge2 = dict(d1, **d2)
>>> print dMerge2
{'mike': 12, 'jack': 19, 'jone': 22, 'ivy': 17}
方法2比方法1速度快很多,方法2等同於:
>>> dMerge3 = dict(d1)
>>> dMerge3.update(d2)
>>> print dMerge
{'mike': 12, 'jack': 19, 'jone': 22, 'ivy': 17}
set
set就像是把Dict中的key抽出來了一樣,類似於一個List,但是內容又不能重復,通過調用set()方法創建:
>>> s = set(['A', 'B', 'C'])
就像dict是無序的一樣,set也是無序的,也不能包含重復的元素。
對於訪問一個set的意義就僅僅在於查看某個元素是否在這個集合裡面:
>>> print 'A' in s
True
>>> print 'D' in s
False
大小寫是敏感的。
也通過for來遍歷:
s = set([('Adam', 95), ('Lisa', 85), ('Bart', 59)])
#tuple
for x in s:
print x[0],':',x[1]
>>>
Lisa : 85
Adam : 95
Bart : 59
通過add和remove來添加、刪除元素(保持不重復),添加元素時,用set的add()方法:
>>> s = set([1, 2, 3])
>>> s.add(4)
>>> print s
set([1, 2, 3, 4])
如果添加的元素已經存在於set中,add()不會報錯,但是不會加進去了:
>>> s = set([1, 2, 3])
>>> s.add(3)
>>> print s
set([1, 2, 3])
刪除set中的元素時,用set的remove()方法:
>>> s = set([1, 2, 3, 4])
>>> s.remove(4)
>>> print s
set([1, 2, 3])
如果刪除的元素不存在set中,remove()會報錯:
>>> s = set([1, 2, 3])
>>> s.remove(4)
Traceback (most recent call last):
File "<stdin>", line 1, in <mole>
KeyError: 4
所以如果我們要判斷一個元素是否在一些不同的條件內符合,用set是最好的選擇,下面例子:
months = set(['Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec',])
x1 = 'Feb'
x2 = 'Sun'
if x1 in months:
print 'x1: ok'
else:
print 'x1: error'
if x2 in months:
print 'x2: ok'
else:
print 'x2: error'
>>>
x1: ok
x2: error
㈥ 如何同步一個python字典有多重
介紹
似乎有很多的扶手椅建議和沒有工作的例子。沒有列在下面,甚至多重的答案,這是頗有幾分失望和不安。由於python愛好者,我們應該支持我們的內置庫,並同時並行處理和同步從來都不是小事,我相信它可以製成瑣碎與適當的設計。這是很重要的現代多核架構,並且不能夠underline!話雖如此
CodeGo.net,我遠遠滿足多處理庫,它仍然是處於起步階段的階段與不少缺陷,錯誤,並正在面向函數式編程(我討厭)。目前我還是比較喜歡火焰兵模塊(這是遙遙領先其對多重的因無法在伺服器運行時共享新創建的對象多處理的嚴重限制。「注冊」的管理對象只能實際注冊一個對象之前管理(或伺服器)開始數落夠了,更多的代碼:
Server.py
from multiprocessing.managers import SyncManager
class MyManager(SyncManager):
pass
syncdict = {}
def get_dict():
return syncdict
if __name__ == "__main__":
MyManager.register("syncdict", get_dict)
manager = MyManager(("127.0.0.1", 5000), authkey="password")
manager.start()
raw_input("Press any key to kill server".center(50, "-"))
manager.shutdown()
多重的SyncManager,可以提供同步共享對象的Server.py在上面的代碼示例。此代碼將不能工作在解釋多處理庫是如何找到「可贖回」為每個注冊的對象相當棘手的運行。運行Server.py將啟動一個定製SyncManager共享多個進程的syncdict字典,並且可以連接到客戶端機或者機器上,或者,如果運行在比回環,其他機器的其他的IP地址。在這種情況下,伺服器運行在環回(127.0.0.1)埠5000。操作syncdict當使用authkey使用安全連接。當任何一個鍵被按下的管理是關機。
Client.py
from multiprocessing.managers import SyncManager
import sys, time
class MyManager(SyncManager):
pass
MyManager.register("syncdict")
if __name__ == "__main__":
manager = MyManager(("127.0.0.1", 5000), authkey="password")
manager.connect()
syncdict = manager.syncdict()
print "dict = %s" % (dir(syncdict))
key = raw_input("Enter key to update: ")
inc = float(raw_input("Enter increment: "))
sleep = float(raw_input("Enter sleep time (sec): "))
try:
#if the key doesn't exist create it
if not syncdict.has_key(key):
syncdict.update([(key, 0)])
#increment key value every sleep seconds
#then print syncdict
while True:
syncdict.update([(key, syncdict.get(key) + inc)])
time.sleep(sleep)
print "%s" % (syncdict)
except KeyboardInterrupt:
print "Killed client"
客戶端端還必須創建一個自定義的SyncManager,注冊「syncdict」,這個沒有傳入一個可調用來檢索共享字典。它定製到5000埠的環回IP地址(127.0.0.1)和authkey建立與管理的安全連接開始Server.py。它通過調用注冊的調用上的管理器檢索共享字典syncdict。它提示如下:
在syncdict的關鍵,操作上
該款項由鍵訪問時的值每個周期
在幾秒鍾內每個周期sleep的金額
然後,客戶端端會檢查看是否存在的關鍵。如果它不它創建的syncdict關鍵。然後,客戶端端進入一個「沒完沒了」循環,它會更新密鑰的值由指定的金額sleep,並列印syncdict只是直到KeyboardInterrupt發生(CTRL
+C)重復此過程。
惱人的問題
該管理器啟動,否則你會得到異常,即使在管理器中的目錄調用就會發現,它確實是有被注冊前管理人必須被調用。
該詞典的所有的操作一定要做的,不是字典(syncdict [「爆破」]=2就會失敗的路多處理器共享自定義對象)
使用SyncManager的將減輕惱人的問題#2,除了惱人的問題#1防止由SyncManager.dict()被注冊和共享返回的代理。
(SyncManager.dict()只能被稱為後的管理器啟動,並注冊只會工作的管理開始之前這樣SyncManager.dict()是做函數式編程和通過代理進程作為一個像文檔的例子做的時候)
在伺服器和客戶端端必須注冊,即使直覺它會看起來像客戶端端將只能夠連接到管理後,看著辦吧(請添加到您的願望清單多處理開發人員)
閉幕
我希望你喜歡這個相當徹底,稍有回答,就像我有。我有一個很大的trouble直在我的腦海,為什麼我掙扎了這么多的多處理模塊,其中火焰兵是一件輕而易舉的,現在多虧了這個答案我已經擊中了要害。我希望這給如何提高多處理器模塊,因為我相信它有一個很大的承諾,但處於起步階段達不到什麼是可能的。盡管描述的惱人的問題,我認為這仍然是一個相當可行的替代方案,是非常簡單的。你可以SyncManager.dict(),並把它傳遞給進程作為該文檔顯示方式,它很可能是一個更簡單的解決方案,根據您的它只是感覺不自然
2.
有沒有字典需要被擺在首位共享的理由嗎?你可以有每一個線程維護自己的字典,並在線程處理或個別線程字典在一起的回撥副本年底實例?
我不知道到底你在做什麼,所以請我的,我的書面計劃可能無法正常工作一字不差。什麼我的建議是更多的是一種高層次的設計理念。
3.
我將致力於一個單獨的進程,以維護「共享字典」:例如: xmlrpclib使代碼提供給其他進程少量,通過xmlrpclib如暴露一個函數,該函數key, increment執行和一個剛服用的key和返回值,用語義細節(是否有丟失的鑰匙,等,等一個默認值),這取決於你的應用程序的需求。
那麼你任何你喜歡的共享專用字典過程方法:從一個簡單的字典一個單線程的伺服器一直到一個簡單的sqlite的資料庫,等等,等等,我建議你開始與代碼「就這么簡單,你可以得到破除「(取決於你是否需要一個永久共享字典,或持久性是沒有必要給你),和,如果需要優化。
4.
響應於適當的溶液中,以並行寫入的問題。我做了非常快速的研究,發現這篇文章是在暗示一個鎖定/信號的解決方案。 (
雖然這個例子是不是特異性的一本字典,我敢肯定,你可以編寫一個基於類的包裝對象,以幫助您基於這種想法詞典的工作。
如果我有一個喜歡這個以線程安全的方式,我倒是Python的信號量解決方案。 (假設我的技術是行不通的。)我相信,信號量普遍放緩,由於其性質阻塞線程的效率。
從網站:
信號量是一個比較先進的信號量有一個內部的計數器,而不是一個鎖標志,並且它只有塊如果超過線程給定數量的試圖保持信號量。根據如何在信號量被初始化,這允許多個線程訪問代碼段
semaphore = threading.BoundedSemaphore()
semaphore.acquire() # decrements the counter
... access the shared resource; work with dictionary, add item or whatever.
semaphore.release() # increments the counter