如何使用列表解析从列表中间丢弃元素?

0 投票
6 回答
619 浏览
提问于 2025-04-15 14:13

我本来可以用索引来做到这一点,但我觉得应该有更简单的方法,能用列表推导式来实现。我是个初学者,希望这个方法不是太明显。谢谢!

for x in firstList:
    firstFunc(x)
    secondFunc(x)
    x = process(x)
    if x.discard == True:
        (get rid of x)
secondList.append(firstList)

6 个回答

0

几点说明:

  • 你不能用 append 来添加列表的内容,应该用 extend
  • 没有必要写 == True 这种形式,直接用 if x.discard: 就可以了。
  • 最好是创建一个新列表,里面放你不想丢弃的值,这样就不会在循环中搞得一团糟。

所以你可以这样做:

tmp = []
for x in first_list:
    x = process(x)
    if not x.discard:
        tmp.append(x)
second_list.extend(tmp)

当然,用列表推导式会更符合 Python 的风格:

[i for i in first_list if not process(i).discard]
2

只是随便想想,这对文档帮助不大,但为什么不试试呢:

def masterFunc(x):
    firstFunc(x)
    secondFunc(x)
    process(x)
    return x.discard

secondList = [ x for x in firstList if masterFunc(x) ]

好消息:严格来说,它完成了你要求的功能。
坏消息:它把firstFunc、secondFunc和process给隐藏起来了。

听起来你在这个例子中已经遇到了副作用和命令/查询分离的问题,所以我觉得这个小技巧并没有想象中那么好,可能只是稍微清理一下代码而已。你可能会发现,有些方法需要反转(比如用x.firstFunc()而不是firstFunc(x)),还有些方法需要拆分开来。也许还有比'x.discard'更好的方式来处理过滤。

1

你知道吗,其实最好的办法就是按照你喜欢的方式初始化 secondList,然后在一个普通的循环里执行这三个函数,因为它们之间是有依赖关系的,而且每个函数的逻辑不仅仅是过滤(你提到的处理设置属性……我猜你的意思是除了丢弃之外的其他操作):

# If secondList not initialized...
secondList = []
for x in firstList:
    firstFunc(x)
    secondFunc(x)
    process(x)
    if not x.discard:
        secondList.append(x)

在这里,列表推导式帮助不大,因为你在每个函数里都在处理数据(不过它们确实可以减少一两行代码;这要看你对“干净”代码的定义)。如果 process() 只是判断某个项目是否应该在新列表里,返回 True 或 False,那下面的写法在我看来会更好。


如果 firstFunc(x) 和 secondFunc(x) 在 process() 之后确实改变了 x.discard 的结果,而 process(x) 的结果就是 x,那么在你的情况下我会这样做:

for x in firstList:
    firstFunc(x)
    secondFunc(x)
secondList = [ x for x in firstList if not process(x).discard ]

不过,如果 process(x) 的结果和 x 不一样,就像你的示例所显示的那样,你也可以把最后一行改成这样:

interimList = [ process(x) for x in firstList ]
secondList = [ x for x in interimList if not x.discard ]

注意,如果你想把这些结果添加到 secondList 中,可以使用 secondList.extend([...])。

补充:我意识到我错误地写了“do not”改变,但我想说的是如果它们确实改变了 process() 的结果。

补充 2:清理描述和代码。

撰写回答