x = ['a', 'b', 'c', 'd']
%%timeit
y = x[:] # fastest way to copy
y.remove('c')
1000000 loops, best of 3: 203 ns per loop
%%timeit
y = list(x) # not as fast copy
y.remove('c')
1000000 loops, best of 3: 274 ns per loop
%%timeit
y = [n for n in x if n != 'c'] # list comprehension
1000000 loops, best of 3: 362 ns per loop
%%timeit
i = x.index('c')
y = x[:i] + x[i + 1:]
1000000 loops, best of 3: 375 ns per loop
如果你使用最快的方法复制一个列表(它不是很可读),你将比使用列表解析快45%。但是如果你使用list()类(这是一个更常见的Python类)复制列表,那么你将比使用列表解析慢25%。 真的,一切都很快。我认为.remove()比list a list comprehension技术更具可读性,但它不一定更快,除非你有兴趣在重复中放弃可读性。 在这种情况下,列表解析的最大优点是它更简洁(即如果你有一个函数要从一个给定的列表中删除一个元素,它可以在一行中完成,而另一个方法需要3行。)有时候一行程序可以非常方便(尽管它们通常以牺牲一些可读性为代价)。此外,在您实际上不知道要删除的元素是否实际上在列表中的情况下,使用列表解析会更好。虽然.remove()会抛出一个ValueError,但列表解析将按预期运行。
suits = ["h", "c", "d", "s"]
noclubs = list(set(suits) - set(["c"]))
# note no order guarantee, the following is the result here:
# noclubs -> ['h', 's', 'd']
def without(iterable, remove_indices):
"""
Returns an iterable for a collection or iterable, which returns all items except the specified indices.
"""
if not hasattr(remove_indices, '__iter__'):
remove_indices = {remove_indices}
else:
remove_indices = set(remove_indices)
for k, item in enumerate(iterable):
if k in remove_indices:
continue
yield item
用途:
li = list(range(5))
without(li, 3)
# <generator object without at 0x7f6343b7c150>
list(without(li, (0, 2)))
# [1, 3, 4]
list(without(li, 3))
# [0, 1, 2, 4]
9条答案
按热度按时间ryhaxcpt1#
u91tlkcl2#
如果您不需要单独的
noclubs
jfewjypa3#
这个问题已经得到了回答,但我想解决使用列表解析比使用
.remove()
慢得多的评论。我的机器上的一些配置文件(notebook使用Python 3.6.9)。
如果你使用最快的方法复制一个列表(它不是很可读),你将比使用列表解析快45%。但是如果你使用
list()
类(这是一个更常见的Python类)复制列表,那么你将比使用列表解析慢25%。真的,一切都很快。我认为
.remove()
比list a list comprehension技术更具可读性,但它不一定更快,除非你有兴趣在重复中放弃可读性。在这种情况下,列表解析的最大优点是它更简洁(即如果你有一个函数要从一个给定的列表中删除一个元素,它可以在一行中完成,而另一个方法需要3行。)有时候一行程序可以非常方便(尽管它们通常以牺牲一些可读性为代价)。此外,在您实际上不知道要删除的元素是否实际上在列表中的情况下,使用列表解析会更好。虽然
.remove()
会抛出一个ValueError
,但列表解析将按预期运行。ddrv8njm4#
你可以使用filter(或者itertools中的ifilter)
也可以使用列表结构进行筛选
ddrv8njm5#
如果order * 不重要,可以使用set操作:
kq0g1dla6#
不使用for循环或lambda函数并保持顺序:
我知道它在内部仍然会使用循环,但至少你不必在外部使用它们。
fivyi3re7#
不幸的是,Python中似乎没有默认内置这样的东西。
有几个答案,但我想我会添加一个使用迭代器。如果可以接受就地更换,那将是最快的。如果你不想改变原始的,只想循环一个过滤过的集合,这应该很快:
实施:
用途:
所以它是一个生成器-你需要调用
list
或其他东西来使它永久化。如果你只想删除一个索引,你当然可以通过使用
k == remove_index
而不是一个集合来使它更快。31moq8wy8#
一种可能性是使用
filter
:也可以使用
'c'
的__ne__
方法来代替partial
:然而,后一种方法不被认为是非常pythonic的(通常你不应该直接使用特殊的方法-从双下划线开始),如果列表包含混合类型,它可能会给予奇怪的结果,但它可能比
partial
方法快一点。Python 3.5.2使用IPythons magic
%timeit
命令进行测试。mdfafbf19#
如果你想删除一个 * 特定的 * 元素(而不是仅仅过滤)很重要,你需要类似于以下内容:
如果您的问题确实与扑克牌有关,您也可以考虑在这里使用
set
,以便在语义上更加正确。