我工作在一個範圍通常被包含性描述的域中。我有人類可讀的描述,例如from A to B
,它們表示包括兩個端點的範圍 - 例如, from 2 to 4
表示2, 3, 4
。我應該如何處理Python中的包含範圍?
在Python代碼中使用這些範圍的最佳方式是什麼?下面的代碼工作,以生成一個整數包括的範圍,但我也需要執行包片操作:
def inclusive_range(start, stop, step):
return range(start, (stop + 1) if step >= 0 else (stop - 1), step)
唯一的完整的解決方案,我看到的是明確使用+ 1
(或- 1
)我每次使用range
或分時符號(例如range(A, B + 1)
,l[A:B+1]
,range(B, A - 1, -1)
)。這種重複真的是使用包容性範圍的最佳方式嗎?
編輯:感謝L3viathan回答。寫一個inclusive_slice
功能,以補充inclusive_range
當然是一個選擇,雖然我可能會寫如下:
def inclusive_slice(start, stop, step):
...
return slice(start, (stop + 1) if step >= 0 else (stop - 1), step)
...
這裏代表代碼來處理負指數,用切片使用時並不簡單 - 注意,例如,如果slice_to == -1
,L3viathan的功能給出不正確的結果。
但是,看起來inclusive_slice
函數會使用起來很尷尬 - l[inclusive_slice(A, B)]
真的比l[A:B+1]
更好嗎?
有沒有更好的方法來處理包含範圍?
編輯2:謝謝你的新答案。我同意弗朗西斯和科利的觀點,即改變全球或某些類別的切片操作的含義會導致重大混亂。因此,我現在傾向於編寫一個inclusive_slice
函數。爲了回答我之前編輯的問題,我得出結論:使用這樣的函數(例如l[inclusive_slice(A, B)]
)會比手動添加/減少1(例如l[A:B+1]
)更好,因爲它會允許邊界情況(如B == -1
和B == None
)將在一個地方處理。我們可以減少使用該功能的尷尬嗎?
編輯3:我一直在想如何改進使用語法,目前看起來像l[inclusive_slice(1, 5, 2)]
。特別是,如果包含切片的創建類似於標準切片語法,那將是一件好事。爲了實現這個功能,可以使用inclusive
而不是inclusive_slice(start, stop, step)
,該功能將切片作爲參數。對於inclusive
理想的使用語法是行1
:
l[inclusive(1:5:2)] # 1
l[inclusive(slice(1, 5, 2))] # 2
l[inclusive(s_[1:5:2])] # 3
l[inclusive[1:5:2]] # 4
l[1:inclusive(5):2] # 5
不幸的是,這是不Python,只允許內[]
使用:
語法允許的。因此必須使用語法2
或3
(其中s_
的行爲如the version provided by numpy)來調用inclusive
。
其他可能性是使inclusive
成一個對象與__getitem__
,允許語法4
,或者應用inclusive
僅向片的stop
參數,如在語法5
。不幸的是,我不相信後者可以工作,因爲inclusive
需要知道step
的價值。
在可行的語法(原始l[inclusive_slice(1, 5, 2)]
,加上2
,3
和4
),這將是最好的使用?還是有另一種更好的選擇?
最後修改:謝謝大家的回覆和評論,這已經非常有趣了。我一直都是Python「做它的一種方式」哲學的忠實粉絲,但是這個問題是由Python的「單向」和問題域所禁止的「單向」之間的衝突造成的。在語言設計中,我確實獲得了TIMTOWTDI的一些讚賞。
給了第一和投票最高的答案,我要獎勵的賞金L3viathan。
請注意,你寫的功能是不正確的。第二個參數「stop + step」有可能使包含範圍超出應有的範圍。它應該是'stop + 1'。例如'range(0,7,3)'是'[0,3,6]',但是你的函數會給出'[0,3,6,9]'。 – Shashank
域中的元素是否始終是整數?我的意思是'從2到4'可以表示爲'[2,3,4]'或'2:00,2:01,...,4:00'。 –
@qarma - 是的,就像內置的range()函數一樣,我只需要處理整數範圍。 – user200783