[英]Is there a more efficient one liner to initialize a variable based on a condition?
可以通過一個內襯初始化atype
變量嗎?
def detect(dt,result):
""" prints the type of date """
atype = 'unknown'
if 'greg' in result:
atype = 'Gregorian'
elif 'eth' in result:
atype = 'Ethiopian'
print '%s is in %s format.' % (dt,atype)
您可以使用一對條件表達式-不需要括號。 就像Python知道應該從左到右合理地完成1 + 2 + 3
,因此條件表達式可以一個接一個地寫在另一個子句中,而不必擔心解釋器會感到困惑。 換行和縮進對於提高可讀性很重要,因此,我通常這樣做:
atype = ('Gregorian' if 'greg' in result
else 'Ethiopian' if 'eth' in result
else 'unknown')
壓痕的這種形式不僅是大多數編輯器將在任何情況下,如果按之前的每個“輸入”產生一個else
,但它使得視覺感很大,我當我回來以后讀我自己,或者是有人否則就是代碼-畢竟,這是我們使用Python的重要原因,對吧? :)
編輯:當然,我意識到這只是單行代碼,因為Python將連續的行視為單行代碼。 所以我想我的答案是,對於我來說,您的程序看起來像Python的一條物理線有點密集,但是如果編寫為Python的一條邏輯線,您的程序將非常不錯!
編輯:另一個注意事項:當然,我認識到我的代碼片段違反了PEP-8,PEP-8表示要終止與運算符的連續行-因此PEP-8將讓我將else
詞移到上一行的末尾。 我只能說這是我不同意的PEP-8規則之一,我經常破壞它,因此我產生了更具可讀性的代碼。 我認為在這一點上,我與PEP-8的不同之處在於具有數學排版背景,並且,正如Donald Knuth在TeXBook中強調的那樣,“顯示的公式總是在二進制運算和關系之前中斷”(第195頁)。
不知道這是否有意義和可讀...
atype = 'Gregorian' if 'greg' in result else ('Ethiopian' if 'eth' in result else 'unknown')
我個人在一個論壇上提出
def detect(dt,result):
""" prints the type of date """
style = 'Gregorian' if 'greg' in result else\
'Ethiopian' if 'eth' in result else\
'unknown'
print '%s is in %s format.' % (dt,style)
在我的代碼的秘密中,沒有人會來看我是否尊重Python的Zen,我實際上會這樣做:
def detect(dt,result):
""" prints the type of date """
print dt + ' is in %s format.'\
% \
'Gregorian' if 'greg' in result else\
'Ethiopian' if 'eth' in result else\
'unknown'
我測量了執行時間:第二次執行的時間是第一次執行時間的89%
。
最后,我進行的測試並不令我滿意,因為將完成分配的程序(樣式=等)與沒有等效分配的程序進行比較是不公平的。
因此,我再次使用修改后的代碼進行了測試。為強調代碼之間差異的影響,我添加了一些條件行。
我分別運行以下程序(以避免在不必重新創建的情況下重新分配對象的可能的持久性;我不確切知道Python的內存和對象模型中發生了什么,以及是否可能實際上發生了;但是在衡量執行時間時,有時會發現奇怪的現象。因此,我沒有風險,我將代碼分開)
第一個程序
from time import clock
A=[]
for repeat in xrange(5000):
def detect(dt,result):
if 'greg' in result:
h = '%s is in %s format.' % (dt,'Gregorian')
elif 'eth' in result:
h = '%s is in %s format.' % (dt,'Ethiopian')
elif 'ame' in result:
h = '%s is in %s format.' % (dt,'American')
elif 'rus' in result:
h = '%s is in %s format.' % (dt,'Russian')
elif 'egyp' in result:
h = '%s is in %s format.' % (dt,'Egyptian')
else:
h = '%s is in unknown format.' % dt
te = clock()
for i in xrange(10000):
detect('zozo',' he is egyptolog')
A.append(clock() - te)
print min(A)
第二程序
from time import clock
B=[]
for repeat in xrange(5000):
def detect(dt,result):
x = '%s is in %s format.' % (dt,'Gregorian' if 'greg' in result else\
'Ethiopian' if 'eth' in result else\
'American' if 'ame' in result else\
'Russian' if 'rus' in result else\
'Egyptian' if 'egyp' in result else\
'unknown')
te = clock()
for i in xrange(10000):
detect('zozo',' he is egyptolog')
B.append(clock() - te)
print min(B)
第三程序
from time import clock
C = []
for repeat in xrange(1000):
def detect(dt,result):
y = dt + ' is in %s format.'\
% \
'Gregorian' if 'greg' in result else\
'Ethiopian' if 'eth' in result else\
'American' if 'ame' in result else\
'Russian' if 'rus' in result else\
'Egyptian' if 'egyp' in result else\
'unknown'
te = clock()
for i in xrange(10000):
detect('zozo',' he is egyptolog')
C.append(clock() - te)
print min(C)
。
我獲得了
0.0198832秒
0,019962秒
0,012664秒
結論:
使用if-elif-else條件或if-else-else-else連續條件編寫代碼的方式之間沒有區別。
然后,即使第二種方式並不比delnan認為的那么殘酷,但它的可立即理解性卻稍差一些,因此我最終發現,第一種寫作方式由於其完美的可讀性而比第二種寫作方式更好,而且絲毫沒有損失性能。
如果無法使用if-elif-else,例如用於列表理解或編寫lambda函數,則在某些情況下使用if-else-else很有趣,這是唯一的解決方案。
這次,我的代碼運行時間是其他兩次執行時間的64%。 要檢查的條件越多,我的代碼就越快
如果有人擔心性能,則可以使用此解決方案。 如果沒有,對我來說,一系列if-elif-else條件似乎是最佳選擇。
。
@吃,
假設一百萬個元素的列表,像這個
li = [('greg','Gregorian'),('eth','Ethiopian')]
已使用cPickle以序列化格式記錄。 然后代碼將是:
import cPickle
with open('trynewline.txt','r') as f:
li = cPickle.load(f)
def detect(dt,result):
for a,b in li:
if a in result:
return '%s is in %s format.' % (dt,b)
else:
return '%s is in unknown format.' % dt
要么
import cPickle
with open('trynewline.txt','r') as f:
li = cPickle.load(f)
def detect(dt,result):
ha = [ b for a,b in li if a in result]
y = dt + ' is in %s format.'\
% (ha[0] if ha else 'unknown')
就這樣。 無論如何, li中包含的數據必須來自某個地方。 它可以自動生產; 或手動生產。 如果它是手工制作的,並且沒有人在我之前創建,那么我將不得不自己寫一百萬個條件。 如果是您必須編寫代碼,那么您也將這樣做。 我看不出如何用字典避免這種情況。
是的,Python變量的范圍與其他編程語言有點不同。 所以,
if 'greg' in result:
atype = 'Gregorian'
print(atype)
會做的很好。 也
if 'greg' in result: atype = 'Gregorian'
print(atype)
可以使用,除非它是Python Shell(您必須執行整個腳本)
但是無論如何,進行非常長的,與條件相關的變量初始化是一個不好的做法。
其實很奇怪,但是..這只是一種不同的方式..我認為擴展起來更容易,但是我想還有更好的方法;)
import operator as op
import functools as fc
atype = {'greg':'Gregorian', 'eth':'Ethiopian'}.get(filter(fc.partial(op.contains, ('greg', 'eth')), res)[0], 'unknown')
盡管有單獨的行來設置字典,但這里有一個單行(為了便於閱讀,請展開兩行):
typemap = {'greg': 'Gregorian', 'eth': 'Ethiopian'}
atype = ([typemap[frag] for frag in typemap if frag in result][0]
if any(frag in result for frag in typemap) else 'unknown')
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.