Python:有临时的pop方法吗?
有没有像pop这样的方法可以临时删除列表中的一个元素,而不永久更改原始列表? 一个可以执行以下操作的程序:Python:有临时的pop方法吗?,python,list,filter,Python,List,Filter,有没有像pop这样的方法可以临时删除列表中的一个元素,而不永久更改原始列表? 一个可以执行以下操作的程序: def newpop(list, index): return(list[:index] + list[index+1 :] 列表=[1,2,3,4] newpop(list,0)返回[2,3,4] 名单未变 我来自R,如果我想暂时删除某个列表的最后一个元素,我只需要做c(1,2,3,4)[-4],所以如果我在这里向后思考,请原谅 我知道我可以编写如下函数: def newpop(
def newpop(list, index):
return(list[:index] + list[index+1 :]
def newpop(list, index):
return(list[:index] + list[index+1 :]
,但它似乎过于复杂?任何提示都将不胜感激,我正在努力学习更多地思考Python而更少地思考R。我可能把“临时”位看得太过冗长,但您可以定义一个contextmanager
以从列表中弹出项,并在您使用列表时插入:
from contextlib import contextmanager
@contextmanager
def out(lst, idx):
x = lst.pop(idx) # enter 'with'
yield # in `with`, no need for `as` here
lst.insert(idx, x) # leave 'with'
lst = list("abcdef")
with out(lst, 2):
print(lst)
# ['a', 'b', 'd', 'e', 'f']
print(lst)
# ['a', 'b', 'c', 'd', 'e', 'f']
注意:这不会创建列表的副本。使用
期间对列表所做的所有更改都将反映在原始列表中,直到索引不再有效时,将元素重新插入列表可能会失败
还要注意,弹出元素然后将其放回列表将根据位置具有高达O(n)的复杂性,因此从性能角度来看,这也没有真正意义,除非您希望在复制列表时节省内存
与您的newpop
函数更相似,也可能更实用,您可以使用enumerate
的列表理解功能来创建列表的副本,而不会出现不符合要求的位置。这不会创建两个临时切片,并且可能更具可读性,并且不太容易出现一个接一个的错误
def without(lst, idx):
return [x for i, x in enumerate(lst) if i != idx]
print(without(lst, 2))
# ['a', 'b', 'd', 'e', 'f']
您还可以通过简单地将[…]
更改为(…)
,即返回(x表示…)
,将其更改为返回生成器表达式。这将是列表上的某种只读“视图”,而不创建实际副本。为什么您认为您的代码很复杂?它看起来很好,我试着将它与R进行比较,在R中,我只需执行上面显示的简单步骤,它就做到了。所以,直觉上,我认为一定有一种更简单的方法,或者至少有一些原因可以解释为什么它在R中如此简单,而在Python中却不那么简单。这将有助于我理解Python语言,可能=)什么是“临时”的意思,即当您希望恢复原始列表时?你是使用“临时”列表还是只需要位置索引中的元素?简单的回答是:不,没有等效的内置方法。简单地创建一个新列表似乎更有意义,就像你的函数已经做过的那样。这可能是一个很好的上下文管理器示例,适用于以前没有使用过它们的人,但出于大多数实际目的,问题中的原始代码可能不太容易出错,而且更有用。@user2357112supportsMonica为我辩护,我想我在解释中已经清楚地说明了这一点,我也不认为这是公认的答案。@tobias_k:我喜欢列表理解中的枚举,非常感谢!