需要一种在迭代时删除元素后固定列表大小的解决方案。
无法创建新列表,因为存在较大问题(800次迭代),并且每次创建新列表在计算上都是昂贵的
list = [1,2,3,4,5,6,7,8,9,10]
for i in range (len(list)):
if a[i] < 6:
del a[i]
输出应该是原始列表,现在带有值
[6,7,8,9,10]
答案 0 :(得分:1)
仅覆盖当前列表
lst = [1,2,3,4,5,6,7,8,9,10]
lst =[i for i in lst if i>=6]
# lst = [6,7,8,9,10]
答案 1 :(得分:1)
有关性能评估,请参见此答案末尾的UPDATE
如果仅要删除列表中的一个元素(或列表开头的元素),则可能需要查找索引,而不要遍历所有元素:
index = lst.index(6)
del lst[:index]
如果在遍历列表时担心索引偏移,则可以跟踪已删除条目的数量并相应地计算实际索引:
originalLen = len(lst)
for originalIndex in range(originalLen):
i = originalIndex - originalLen + len(lst)
if lst[i] < 6:
del lst[i]
您甚至可以通过创建一个为您做家务的迭代器来对此进行概括:
def stableIndexes(lst):
oLen = len(lst)
for oi in range(oLen): yield oi - oLen + len(lst)
for i in stableIndexes(lst):
if lst[i] < 6:
del lst[i]
如果要删除多个项目,则可以创建索引列表以在循环结束时以相反的顺序删除和处理它们:
indexes = []
for i,a in enumerate(lst):
if a > 2 and a < 5:
indexes.append(i)
for index in reversed(indexes):
del lst[index]
或者您可以按照相反的顺序处理列表,并在删除索引时将其删除,而不会混淆索引:
for i in range(len(lst)-1,-1,-1):
if lst[i] > 2 and lst[i] < 5:
del lst[i]
另一种方法是在删除至少一个项目后手动移动后续项目,并在末尾截断列表:
i = 0
for index,a in enumerate(lst):
if a > 2 and a < 5:
continue
if i < index:
lst[i] = a
i += 1
del lst[i:]
最后,另一种方法是将“无”分配给要删除的项目,并在后续迭代中跳过“无”值:
for i,a in enumerate(lst):
if a is None: continue
if a > 2 and a < 5:
lst[i] = None
...
UDATE
我进行了一些性能测试,从1,000,000个元素列表中删除了条目。事实证明,使用列表理解(即制作列表的第二个副本)比我上面描述的所有方案都快:
Method del 1 in 13 del only 1
---------------------------------- ----------- ----------
New list (using comprehension): 0.00650 0.00799
Assign None to deleted items: 0.00983 0.01152
Manually shifting elements: 0.01558 0.01741
Delete as you go in reverse order: 0.07436 0.00942
List of indexes to delete: 0.09998 0.01044
因此,创建新列表的“计算上昂贵”的理论在实践中并不成立。与所有其他方法相比,就处理时间而言,它实际上是最经济的方法。
这很可能是由COW(写时复制)内存管理引起的,该管理将在您更改列表中的某些内容后立即分配内存。因此,总会(内部)创建一个新列表。
通过自己显式创建一个新列表,您可以利用此内存分配,并节省列表内存空间内数据的任何其他移位。
最后,您应该让Python处理这些问题。
答案 2 :(得分:0)
首先,使用列表推导更容易:
lst = [1,2,3,4,5,6,7,8,9,10]
t = [x for x in lst if x >= 6]
print(t)
如果不允许创建新的list
对象,则始终可以使用生成器表达式:
lst = [1,2,3,4,5,6,7,8,9,10]
g = (x for x in lst if x >= 6)
for val in g:
print(val)
答案 3 :(得分:0)
一种安全的解决方案(如果修改了一个列表,在任何程度上对其进行迭代都可以称为“安全”),请向后迭代:
n = len(list_)
for i in xrange(n):
idx = n - i - 1
if list_[idx] < 6:
del list_[idx]
这样,您至少不会对列表的未更改部分产生影响。