我发现了这个问题,要求对数组进行就地修改,以便将所有零移动到数组的末尾,并保持非零元素的其余顺序。根据问题陈述,就地意味着无需复制原始数组。 (摘自Leetcode,可以找到#283,零位移动)
输入和输出的示例为[0,1,0,13,12]变为[1,13,12,0,0]。我看到的一个简单的解决方案是:
for num in nums:
if num == 0:
nums.remove(num)
nums.append(0)
解决方案清晰易懂,因此我知道它正在执行应有的操作。
但是,由于我不确定在后台如何执行删除操作,因此在就地部分上无法完全清除/出售。在内部删除是否会复制数组以删除指定的元素-它如何工作?使用“就地”这一概念,下面我的初始解决方案是否就地考虑(因为它不会复制nums,而是修改了nums的原始版本)?
indices = []
for en, num in enumerate(nums): # get the index of all elements that are 0
if num == 0:
indices.append(en)
for en, i in enumerate(indices):
new_i = i-en # use the index, accounting for the change in length of the array from removing zeros
nums = nums[:new_i] + nums[new_i+1:] # remove the zero element
nums = nums + [0] * len(indices) # add back the appropriate number of zeros at the end
答案 0 :(得分:0)
是否在内部删除数组的副本以删除指定的元素?
否
它如何工作?
从python source code for lists,remove()
调用listremove()
:
listremove(PyListObject *self, PyObject *v)
{
Py_ssize_t i;
for (i = 0; i < Py_SIZE(self); i++) {
int cmp = PyObject_RichCompareBool(self->ob_item[i], v, Py_EQ);
if (cmp > 0) {
if (list_ass_slice(self, i, i+1, (PyObject *)NULL) == 0)
Py_RETURN_NONE;
return NULL;
}
else if (cmp < 0)
return NULL;
}
PyErr_SetString(PyExc_ValueError, "list.remove(x): x not in list");
return NULL;
}
Python在要删除的项目的索引处切片列表。我找到了对删除功能here的更好描述:
arguments: list object, element to remove
returns none if OK, null if not
listremove:
loop through each list element:
if correct element:
slice list between element's slot and element's slot + 1
return none
return null
就您的“就地”概念而言,我想说它已经就位,并且适合您的特定情况。但是有人已经注意到,在迭代列表时不要修改列表。