簡體   English   中英

鑒於任意收集,有沒有辦法告訴它是否被訂購?

[英]Given an arbitrary collection, is there a way to tell if it is ordered?

這是我到目前為止所擁有的:

def is_ordered(collection):
    if isinstance(collection, set):
        return False
    if isinstance(collection, list):
        return True
    if isinstance(collection, dict):
        return False

    raise Exception("unknown collection")

有沒有更好的方法來做到這一點?

NB:我的意思是有序而不是排序。

動機:

我想迭代一個有序的集合。 例如

def most_important(priorities):
    for p in priorities:
        print p

在這種情況下,優先級有序的事實很重要。 什么樣的收藏不是。 我想在這里打鴨子。 我經常被Pythonistas的類型檢查所勸阻。

如果集合真的是任意的(意味着它可以是任何類),那么答案必須是否定的

基本上,有兩種可能的方法:

  1. 了解可以呈現給您的方法的每個可能的類,以及它是否有序;
  2. 通過將每個可能的鍵組合插入其中,並查看是否保留了順序來自己測試該集合。

后者顯然是不可行的。 前者與你已經擁有的一致,除了你必須知道每個派生類,如collections.OrderedDict ; 檢查dict是不夠的。

坦率地說,我認為整個is_ordered check是一種蠕蟲。 你為什么要這樣做呢?

更新:實質上,您正試圖對傳遞給您的參數進行單元測試。 停止這樣做,並對您自己的代碼進行單元測試。 測試您的消費者(確保它與有序集合一起使用),並對調用它的代碼進行單元測試,以確保它獲得正確的結果。

在靜態類型語言中,您只需將自己限制為特定類型。 如果你真的想要復制它,只需指定你接受的唯一類型,並測試它們。 如果傳遞任何其他內容,則引發異常。 它不是pythonic,但它可靠地實現了你想要做的事情


那么,你有兩種可能的方法:

  1. 任何帶有append方法的東西幾乎都是有序的;
  2. 如果它只有一個add方法,你可以嘗試添加一個nonce-value,然后遍歷集合以查看nonce是否出現在結尾(或者,可能在一端); 你可以嘗試添加第二個nonce並再次做它只是為了更自信。

當然,這在集合為空的情況下不起作用,或者存在不會在末端添加的排序函數。

可能更好的解決方案只是指定您的代碼需要有序集合,並且只傳遞有序集合。

我認為列舉90%的情況與你將得到的一樣好(如果使用Python 3,用str替換basestring)。 可能還想考慮如何處理生成器表達式和類似的同類(再次,如果使用Py3,跳過xrangor):

generator = type((i for i in xrange(0)))
enumerator = type(enumerate(range(0)))
xrangor = type(xrange(0))
is_ordered = lambda seq : isinstance(seq,(tuple, list, collections.OrderedDict,
                                          basestring, generator, enumerator, xrangor))

如果你的調用者開始使用itertools,那么你還需要添加islice,imap,groupby返回的itertools類型。 但這些特殊情況的絕對數量真​​正開始指向代碼氣味

如果沒有訂購列表怎么辦,例如[1,3,2]?

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM