【问题标题】:Is it possible to ignore the last element of a list without having to create another list and without modifing the original list?是否可以忽略列表的最后一个元素而不必创建另一个列表并且不修改原始列表?
【发布时间】:2019-03-25 16:42:42
【问题描述】:

在使用for 时,我需要忽略列表的最后一个元素,而不需要创建任何其他列表或修改进程中的主列表。

并且不忽略最后一个元素,如果它在任何其他位置重复,而不是最后一个。所以,只忽略它的位置。

我在这里忽略它,但我必须创建 1 个额外的列表:

list1 = [3,2,3] list1_without_last = list1
list1_without_last.remove(list1_without_last[len(list1_without_last)-1])
for i in list1_without_last :
    #do something

我需要这样的东西:

list1 = [3,2,3] for i in list1 except_list1_last_element:

Ex1: list3 =[4,5,4,5] 输出:[4,5,4]

Ex2:list4 =[1,2,3,4] 输出:[1,2,3]

【问题讨论】:

标签: python python-3.x


【解决方案1】:

这个怎么样?

list1 = [3, 2, 3]
for i in list1[:-1]:
    print(i)

如果不创建任何中间副本是硬性要求,您可以使用itertools.islice

import itertools
list1 = [3, 2, 3]
for i in itertools.islice(list1, len(list1) - 1)):
    print(i)

【讨论】:

  • list1[:-1] 不创建列表吗?
  • “如果最后一个元素在任何其他位置重复,则忽略最后一个元素。”
  • list1[:-1] 确实创建了一个新列表。这可以通过id(list1)id(list[:-1] 不匹配来检查,如果我没记错的话。
【解决方案2】:

规范的方法是使用range 按索引访问项目。将索引与列表的长度进行比较是检查它是否是最后一个元素的最简单方法。

for i in range(len(some_list) - 1):
    item = some_list[i]

对于不支持len 或索引的迭代器,另一种方法是保留带有itertools.tee 的迭代器的前瞻副本,并在前瞻到达末尾时停止原始运算符的迭代。这还有一个优点是可以直接概括以删除最后的n 元素。

from itertools import tee, islice

def drop_last(it, n=1):
    it, lookahead = tee(iter(it))
    next(islice(lookahead, n, n), None)
    for _ in lookahead:
        yield next(it)

for x in drop_last([1, 2, 3]):
    print(x)
# output:
# 1
# 2

【讨论】:

  • “如果最后一个元素在任何其他位置重复,则忽略最后一个元素。”
  • 这不是我在做什么吗?
  • 我相信如果最后一个元素以某种方式在其他地方重复,则必须保留它。
  • 我的猜测是这个有点神秘的陈述意味着我们不能删除最后一个元素按值,因为它可能出现在其他位置。但如果没有 OP 的澄清,我们都只是在这里猜测。
  • @Dion 这是我在写这个答案时的理解
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-08-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-03-31
  • 1970-01-01
相关资源
最近更新 更多