的对象,当放入列表中时该对象会自动消失。

例如,{a, b, Nothing, c, d, Nothing}自动计算为{a, b, c, d}

python 是否存在类似的东西?

我尝试x = (1, 2, 3, 4 if True, 5)抱怨缺少 else 语句。移动到x = (1, 2, 3, 4 if True else None, 5)成功,但y = (1, 2, 3, 4 if False else None, 5)给出了(1, 2, 3, None, 5),而我想要的是(1, 2, 3, 5),所以None被保留,同时Nothing会被丢弃。

如果有这样的东西,它对[lists,]和有效吗{'dict': 'ionaries'}

19

  • 4
    您可以在创建列表期间或之后使用或 推导式filter()来取出项目。Nonefilter()


    – 


  • 的确。在列表理解中,您不需要 else,它会提供过滤器。但我想要一个手工创建的列表。我不介意做过滤器,因为我得到的元组很小,但看起来很丑。


    – 

  • 3
    为什么你想要拥有无论如何都会消失的元素?


    – 

  • 该应用程序似乎非常特定于 Mathematica。 Python 中的用例是什么?


    – 

  • 1
    这对你有用吗tuple(i for i in range(1, 6) if i != 4 or False)


    – 


3 个回答
3

(4,) if True else ()计算结果为元组(4,)或空元组(),因此将其解包后您可以编写x = (1,2,3,*((4,) if True else ()),5)

几乎完全相同的事情适用于列表,x = [1,2,3,*((4,) if True else ()),5].

解压字典也可以:x = {'a':1, **({'b':2} if True else {})}.

我只会使用None然后一个过滤器。

x = (1, 2, 3, None, 5)
x = tuple(filter(None, x))

如果你想要单行:

x = tuple(x for x in (1, 2, 3, None, 5) if x is not None)
# or
x = tuple(filter(None, (1, 2, 3, None, 5)))

如果你想要一个构造元组的函数,你可以使用:

def tup(*items):
    return tuple(filter(None, items))

x = tup(1,2,3,None,5)

4

  • 1
    注意:如果None是您在序列中期望的唯一错误值,则filter(None, ...)无需使用庞大的 lambda 即可正常工作。


    – 


  • 哦,谢谢!我会更新


    – 

  • 如果我要达到工业强度,我可能会创建一个哨兵来确保实际上没有任何内容被过滤掉,但这是一个很好的演示。


    – 

  • @evanb。是的,但是创建一个单例类对于这个问题来说可能有点过分了。


    – 

每种编程语言都有一套自己的基本概念和思想,即使其中许多概念和思想在大多数流行语言中共享,但有些是特定于语言的。 Python 作为编程语言和编码哲学并不带有NothingMathematica 意义上的概念。

Nothing在 Python 中,需要使用None浮点数来表达的概念,浮点数float("nan")本身就是特殊的 Python 对象,表示缺少有效值。

作为介绍,让我们提供一个 Python 构造,它类似于Nothing问题中提到的 Mathematica 意义上的用法:

x = (1, 2, 3, *(), 5)

换句话说,在这个特定的用例中,只有与 Mathematica 等效的 PythonNothing是:

* ()

在字典的上下文中:

**{}

d = {'a':1, **{}, 'c':3 }

正如deceze在评论中提到的,这个构造本身作为占位符的用途非常有限,用于将来的替换标记在列表中的位置。让我们举一些例子,其中使用这种构造确实更有意义:

x = [ 1, 2, *(3 if False else ()), 4 ]
d = {'a':1, **({'b':2} if False else {}) , 'c':3 }

替换False为任何适合用例的适当条件,以实现更有用的使用用例。

为了完整起见,让我们提到使用可用于 Python 列表的列表添加来实现相同/相似功能的另一种可能方法:

x = [ 1, 2 ] + [] + [ 4 ]
x = [ 1, 2 ] + [*([3] if False else ())] + [ 4 ]

此结构也可用于字典:

d = dict( [('a',1)] + [] + [('c',3)] )
d = dict( [('a',1)] + [*(('b',2) if False else ())] + [('c',3)] )

else如果您出于某种原因想避免在条件表达式中使用关键字,您可以使用以下“技巧”:

x = [ 1, 2, *(_ for _ in [3] if False), 4]
d = dict( [('a',1)] + [*(_ for _ in [('b',2)] if False)] + [('c',3)] )

虽然可能有点“脏”,但可能更容易理解,并且更适合阅读者的眼睛,因为强调[3][(‘b’,2)]吸引眼球,使得嵌入它的表达不那么突兀。


注意在 Python 中,*()和 都不会像在 Mathematica 中那样工作。例如,您无法替换列表元素以使其消失。例如,要从列表 x 中删除 3,您需要实际删除它:**{}NothingNothing

x.pop(x.index(3))

换句话说,正如deceze在对您的问题的评论中已经正确提到的那样:

MathematicaNothing似乎有非常具体的用例,这些用例与 Python 无关,因此不存在等效的用例

PS 我知道用 Nothing 替换某些东西,从而使该东西消失而存在的想法对于 Python 程序员来说有点陌生,并且让人想知道它有什么好处。与受 Python 编码影响的另一种思维方式不同,Nothing 的概念可能显得非常有用和重要,值得重新思考,甚至​​是 PEP 的理由。

当您在 Mathematica 文档中心阅读该功能的描述并且不注意大写字母时,肯定值得一笑或大笑。在这种情况下,您将阅读:

释放保留后,不会删除任何内容。

代替

当释放保留时,没有任何内容被删除。

😀 😀 😀 😀 😀 😀 😀 😀 😀 😀 😀 😀 😀 😀 😀

是的……这个概念Hold对于 Python 来说也是陌生的,但如果与Nothing.

8

  • 2
    虽然从技术上讲是正确的,但这本身也是完全无用的。 ;-P


    – 

  • 这不是……我会用有意义的案例更新我的答案……


    – 

  • 1
    现在它更有用了。尽管我认为列表理解或简单的几行代码会更Pythonic。但这取决于个人口味。


    – 

  • 1
    x = [ 1, 2, *(3 if False else ()), 4 ]对于 False 情况工作正常,但对于 True 情况则给出TypeError: Value after * must be an iterable, not int


    – 

  • @evanb:谢谢你的提示。更新了我的答案(忘记将 3 作为 [3] 嵌入列表中)


    –