[英]Python sorted consumes tons of memory? (from a power set generator)
我基本上是在尋找其他人對此可能有意見的反饋。 以下內容並非我正在從事的工作,但是示例代碼確實重現了該問題。
我有一個冪集生成器,如果我要發送的基本列表傳遞進來,它會返回所有排列。我需要對生成的集進行排序(在我的實際情況下,返回的集是元組,其值要作為排序依據,下面的示例演示了沒有它的問題)
問題是當我在電源集生成器上使用sorted()時,它消耗了內存。 我意識到2 ^ 50是一個非常大的數字,但是沒有排序的內存使用情況是相當平坦的,因此我想知道是否有更好的方法可以在不超過一兩分鍾的時間內對超大型集合進行排序而不會耗盡內存。 它在帶有Python 2.6.5的Ubuntu上運行。 (在這種情況下也是必需的)
def gen_powerset(seq):
if len(seq) <= 1:
yield seq
yield []
else:
for i in gen_powerset(seq[1:]):
yield [seq[0]]+i
yield i
def main():
initialSet = range(50)
powerset = sorted(gen_powerset(initialSet))
for i in powerset:
print i
if __name__ == "__main__":
main()
免責聲明:如果您嘗試運行此示例,請注意您的內存利用率。 如果樣本接近90%,請按Ctrl-C,因為您的操作系統將開始將內存交換到磁盤。 如果該樣本仍在運行,則磁盤負載將激增,並確實減慢速度,一開始就很難殺死該樣本。
如果不sorted
,則永遠不需要一次存儲超過1個或2個值-因為需要使用生成器( yield
),所以它們會根據需要進行計算。 不幸的是,在不了解整個情況的情況下,沒有一種對列表進行排序的好方法(在查看所有項以確保擁有的項最小之前,您無法從排序中產生值)。
當然,如果您有2個排序的子列表,則可以懶惰地合並它們,因此您可以構建一個不基於合並排序將所有內容立即存儲在內存中的排序,但是在一般情況下效率極低。
sorted
內存使用率較高的原因是它必須立即將所有項目加載到內存中。 自從您編寫了生成器以來,它一次只生成一個元素,而您使用它的方式一次僅使用一個值,因此Python不需要一次保留所有項目。 但是,如果沒有所有可用的內容,就無法對其進行排序。
只要進行排序,就無法解決這個問題,因為排序必須具有所有可用元素。
解決該問題的唯一方法是重寫powerset生成器,以按所需順序生成項目。 這可能會或可能不會,具體取決於您想要的順序。
您正在使用一個生成器,該生成器在消耗它之前一次只能創建一個值,這非常有效地利用了內存。 sorted
功能將需要將其轉換為列表,以便所有這些都一次駐留在內存中。 沒有辦法解決。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.