簡體   English   中英

在Python中對一組值進行分區

[英]Partitioning a set of values in Python

我編寫了一個函數,試圖將值列表划分為連續的塊。 塊是一組值,其中從頭到尾的值將出現在列表中。 例如,考慮列表[1,2,3,7,7,8,9] 這將被分為{1:3, 7:3} 以后我可以讀為以interval that starts at 1 of length 3 and an interval that starts at 7 of length 3

我想出了以下代碼:-

values = list(set(values))
values.sort()
ranges = {}
for value in values:
    if value - i in ranges:
        ranges[value-i] += 1
        i += 1
    else:
        i = 1
        ranges[value] = 0

我很好奇這是否是最好的方法。 將列表轉換為集合然后重新轉換為列表的時間復雜度是多少? 我猜那將是O(n)。

您對如何更好地做到這一點有任何建議嗎?

我們可以做線性的:

values = [7, 3, 2, 7, 1, 9, 8]

range_by_min, range_by_max = {}, {}

for v in values:
    range_by_min[v] = range_by_max[v] = [v, v]

for v in values:
    if v - 1 in range_by_max and v in range_by_min:
        p, q = range_by_max[v - 1], range_by_min[v]
        del range_by_min[q[0]]
        del range_by_max[p[1]]
        p[1] = q[1]
        range_by_max[p[1]] = p

print(range_by_min, range_by_max)

result = {k: v[1] - v[0] + 1 for k, v in range_by_min.iteritems()}
print(result)

結果:

({1: [1, 3], 7: [7, 9]}, {3: [1, 3], 9: [7, 9]})
{1: 3, 7: 3}

這個想法是保留兩個存儲范圍的字典(范圍表示為最小值和最大值的列表)。 第一個將最小鍵映射到范圍。 第二個將最大鍵映射到范圍。

然后遍歷值列表,並加入相鄰范圍。 如果我們訪問的是4,並且有一個范圍4..6,那么我們檢查是否有一個以3結尾的范圍,比方說1..3。 因此,我們將它們加入一個:1..6。

該算法與哈希表訪問呈線性關系。 由於我們希望不斷訪問字典,因此預期的運行時間與值的大小呈線性關系。 通過這種方式,我們甚至不必對輸入數組進行排序。

編輯

我看到了David Eisenstat建議的鏈接 基於此鏈接,可以將實現更新為僅使用一個字典:

ranges = {v: [v, v] for v in values}

for v in values:
    if v - 1 in ranges and v in ranges:
        p, q = ranges[v - 1], ranges[v]
        if p[1] == v - 1 and q[0] == v:
            if q[0] != q[1]:
                del ranges[q[0]]
            if p[0] != p[1]:
                del ranges[p[1]]
            p[1] = q[1]
            ranges[p[1]] = p

result = {k: v[1] - v[0] + 1 for k, v in ranges.iteritems() if k == v[0]}

暫無
暫無

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

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