在一行表达式中定义辅助变量的最优雅的方法

发布于 2025-01-10 16:37:06 字数 1386 浏览 0 评论 0原文

在 Python 的单行表达式中定义辅助变量的最佳方法是什么?我发现了两个:列表理解和“海象”运算符,但两者都可能有点笨重。

示例

假设我想创建一个单行 lambda 排序函数,将日期从美国日期格式排序为时间顺序。我将把字符串拆分成一个由月-日-年组成的三元组,将该元组存储在辅助变量 mdy 中,然后使用该元组的元素作为排序中的键。

我可以使用列表理解来做到这一点:

bash-3.2$ python3
>>> usdates=["2/1/2022", "1/2/2022", "12/31/2021"]
>>> f = lambda x: [(mdy[2], mdy[0], mdy[1]) for mdy in [x.split("/")]][0] 
>>> sorted(usdates, key=f)
['12/31/2021', '1/2/2022', '2/1/2022']

或者通过在“if”子句中使用“walrus”运算符:

bash-3.2$ python3
>>> usdates=["2/1/2022", "1/2/2022", "12/31/2021"]
>>> f = lambda x: (mdy[2], mdy[0], mdy[1]) if (mdy:=x.split("/")) else "ERROR!"
>>> sorted(usdates, key=f)
['12/31/2021', '1/2/2022', '2/1/2022']

这两种方法都有点笨拙。列表理解需要展开单元素列表。但海象运算符只能用在“if”或类似子句中,而这又需要“else”语句。

我真正想要的是这样的东西:

bash-3.2$ python3
>>> f = lambda x: with x.split("/") as mdy: (mdy[2], mdy[0], mdy[1])
  File "<stdin>", line 1
    f = lambda x: with x.split("/") as mdy: (mdy[2], mdy[0], mdy[1])
                  ^
SyntaxError: invalid syntax
>>>

有没有办法在Python 3中做这样的事情?谢谢!

编辑:回应迄今为止的评论说“不要这样做!” -- 我知道这可能不是使用 Python 的最惯用的方式,但我有兴趣找到执行自定义排序的方法,这些排序可以轻松地从命令行调用,也许在带有 shell 命令的管道中调用。

我的主要问题是 Python 是否有比我已经发现的更好的“语法糖”。如果答案是“否”,那也没关系。干杯!

What's the best way to define a helper variable in a one-line expression in Python? I've found two: list comprehension and the "walrus" operator, but both can be somewhat clunky.

Example:

Suppose I want to create a one-line lambda sort function to sort dates from US date format into chronological order. I'm going to split the string into a 3-tuple consisting of month-date-year, store that tuple in a helper variable mdy, and then use the elements of the tuple as keys in the sort.

I could do this using list comprehension:

bash-3.2$ python3
>>> usdates=["2/1/2022", "1/2/2022", "12/31/2021"]
>>> f = lambda x: [(mdy[2], mdy[0], mdy[1]) for mdy in [x.split("/")]][0] 
>>> sorted(usdates, key=f)
['12/31/2021', '1/2/2022', '2/1/2022']

or by using the "walrus" operator inside an "if" clause:

bash-3.2$ python3
>>> usdates=["2/1/2022", "1/2/2022", "12/31/2021"]
>>> f = lambda x: (mdy[2], mdy[0], mdy[1]) if (mdy:=x.split("/")) else "ERROR!"
>>> sorted(usdates, key=f)
['12/31/2021', '1/2/2022', '2/1/2022']

Both methods are somewhat clunky. List comprehension requires unwrapping of a single-element list. But the walrus operator can be used only in an "if" or similar clause, which in turn requires an "else" statement.

What I'm really looking for is something like this:

bash-3.2$ python3
>>> f = lambda x: with x.split("/") as mdy: (mdy[2], mdy[0], mdy[1])
  File "<stdin>", line 1
    f = lambda x: with x.split("/") as mdy: (mdy[2], mdy[0], mdy[1])
                  ^
SyntaxError: invalid syntax
>>>

Is there any way to do something like this in Python 3? Thanks!

EDIT: In response to the comments so far saying "don't do this!" -- I understand that this may not be the most idiomatic way to use Python, but I'm interested in finding ways to perform custom sorting that can be easily called from the command-line, perhaps in a pipeline with shell commands.

My main question is whether Python has any better "syntactic sugar" than what I've already found. If the answer's "no", that's fine. Cheers!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

欢烬 2025-01-17 16:37:06

但是海象运算符只能用在“if”或类似子句中,而这又需要“else”语句

不是真的...

lambda x: [mdy := x.split("/")] and (mdy[2], mdy[0], mdy[1])

列表 comp 允许更好的变量名称,顺便说一句:

lambda x: [(y, m, d) for m, d, y in [x.split("/")]][0]

或者一个函数:

lambda x: (lambda m, d, y: (y, m, d))(*x.split("/"))

But the walrus operator can be used only in an "if" or similar clause, which in turn requires an "else" statement

Not really...

lambda x: [mdy := x.split("/")] and (mdy[2], mdy[0], mdy[1])

The list comp allows nicer variable names, btw:

lambda x: [(y, m, d) for m, d, y in [x.split("/")]][0]

Or with a function:

lambda x: (lambda m, d, y: (y, m, d))(*x.split("/"))
梦亿 2025-01-17 16:37:06

您可以使用 operator.itemgetter 方法来获取和重新排序日期部分

from operator import itemgetter
usdates = ["2/1/2022", "1/2/2022", "12/31/2021"]
f = lambda x: itemgetter(2, 0, 1)(x.split('/'))
sorted(usdates, key=f)

You could use the operator.itemgetter method to fetch and reorder the date parts

from operator import itemgetter
usdates = ["2/1/2022", "1/2/2022", "12/31/2021"]
f = lambda x: itemgetter(2, 0, 1)(x.split('/'))
sorted(usdates, key=f)
仅冇旳回忆 2025-01-17 16:37:06

如果您要处理日期,为什么不将它们视为日期呢?

from dateutil import parser
usdates=["2/1/2022", "1/2/2022", "12/31/2021"]

print(sorted(usdates, key=parser.parse))
['12/31/2021', '1/2/2022', '2/1/2022']

If your dealing with dates, why not treat them a dates?

from dateutil import parser
usdates=["2/1/2022", "1/2/2022", "12/31/2021"]

print(sorted(usdates, key=parser.parse))
['12/31/2021', '1/2/2022', '2/1/2022']
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文