将python列表分成两部分而不需要额外的内存

时间:2017-02-08 11:21:09

标签: python list

我想将l列表l1拆分为两个小列表l2n(我知道分割点l2)。

我已经能够通过复制另一个列表中的l元素然后从n + n/2中删除它们来执行拆分,但这需要为内存中至少l个元素留出空间这是不可承受的,因为{{1}}很大。

有人有解决方案吗?

5 个答案:

答案 0 :(得分:1)

如果您不想在较小的列表上花费额外的内存,您有两种可能:

  1. 您可以在创建较小的列表时销毁/缩小原始列表。您可以使用collections.deque,在两端提供O(1)删除和插入:

    >>> from collections import deque
    >>> deq = deque(range(20))
    >>> front = deque(deq.popleft() for _ in range(10))
    >>> front
    deque([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
    >>> deq  # original list reduced, can be used as 2nd list
    deque([10, 11, 12, 13, 14, 15, 16, 17, 18, 19])
    
  2. 或者您可以在较小列表的某些部分上创建两个视图,这意味着如果修改较小的列表,则会更改原始列表,反之亦然。例如,对您的数字使用numpy.array并在该数组上创建切片(作为视图):

    >>> import numpy as np
    >>> arr = np.array(range(20))
    >>> front = arr[:10]
    >>> back = arr[10:]
    >>> front[3] = 100
    >>> arr  # original list modified
    array([  0,   1,   2, 100,   4,   5,   6,   7,   8,   9,  10,  11,  12,
            13,  14,  15,  16,  17,  18,  19])
    
  3. 如果您必须使用纯Python list,您还可以使用list.pop。但是,如documentation for deque中所述,您不应该使用pop(0),因为每次弹出元素时都必须重新组织整个列表,并提供O(n²)来提取一半列表。而是使用pop()从列表末尾弹出。要恢复原始订单,您可以先弹出一个临时列表,然后从该列表中弹出,将其反转两次。

    >>> lst = list(range(10))
    >>> tmp = [lst.pop() for _ in range(5)]
    >>> front, back = lst, [tmp.pop() for _ in range(len(tmp))]
    >>> front, back
    ([0, 1, 2, 3, 4], [5, 6, 7, 8, 9])
    

答案 1 :(得分:0)

尝试这个怎么样

 addi $s7,$s1,????

然后,class mylist(list): def split_by_position_n(self, n): return self[:int(n)], self[int(n):]

l = mylist(range(1,10))

答案 2 :(得分:0)

您可以使用n from itertools import islice def split_list(lst, n): return islice(lst, n), islice(lst, n, None) A, B = split_list(range(10), 5) print(list(A)) # [0, 1, 2, 3, 4] print(list(B)) # [5, 6, 7, 8, 9] 对列表进行切片。切片对象是惰性的,只有在迭代它们时才会加载到内存中:

<%= form_tag(edit_content_page_dynamic_panel_path(
             parent_page,
             dynamic_panel),
             method: :get,
             available_condition: params[:available_condition]) %>
<p>
<%= text_field_tag :available_condition, params[:avaialble_condition] %>
<%= button_tag "Search", :name => nil, method: :get %>

答案 3 :(得分:0)

Helo AreTor,

这是我的解决方案:

list = [1,2,3,4,5,6,7,8,9]
l1 = list[0:n]
l2 = list[n:]
  • list是元素列表。
  • n是第一个列表中所需元素的数量(分割点索引)。

list [0:n]将返回您列出的前n项。

list [n:]将返回列表的其余部分。

希望它可以帮到你

编辑:如果您担心内存问题,可以在拆分后删除列表。即使您可以在代码中使用list [0:n] / list [n:]而不使用更多内存..

答案 4 :(得分:0)

我带来了一个简单的解决方案。

怎么样?
l1 = [l.pop(0) for i in range(n)]

它似乎有用,它不需要额外的内存。