如何在python lambda中使用wait
我正在尝试这样做:如何在python lambda中使用wait,python,python-3.x,asynchronous,lambda,async-await,Python,Python 3.x,Asynchronous,Lambda,Async Await,我正在尝试这样做: mylist.sort(key=lambda x: await somefunction(x)) 但我得到了这个错误: SyntaxError: 'await' outside async function 这是有意义的,因为lambda不是异步的 我试图使用async lambda x:…,但这会抛出SyntaxError:invalid syntax 国家: 可以提供异步lambda函数的语法,但此构造不在本PEP的范围内 但我无法确定该语法是否在CPython中实现
mylist.sort(key=lambda x: await somefunction(x))
但我得到了这个错误:
SyntaxError: 'await' outside async function
这是有意义的,因为lambda不是异步的
我试图使用async lambda x:…
,但这会抛出SyntaxError:invalid syntax
国家:
可以提供异步lambda函数的语法,但此构造不在本PEP的范围内
但我无法确定该语法是否在CPython中实现
有没有办法声明异步lambda,或者使用异步函数对列表进行排序?你不能。没有
async lambda
,即使有,也不能将其作为键函数传递给list.sort()
,因为键函数将作为同步函数调用,不等待。一个简单的解决方法是自己注释列表:
mylist_annotated=[(等待mylist中x的某个_函数(x),x)]
mylist_注释的.sort()
mylist=[x代表键,x在mylist_注释中]
请注意,只有Python 3.6+才支持列表理解中的await
表达式。如果您使用的是3.5,则可以执行以下操作:
mylist_annotated=[]
对于mylist中的x:
附加((等待一些函数(x,x))
mylist_注释的.sort()
mylist=[x代表键,x在mylist_注释中]
斯文·马纳奇的答案有一个边缘案例
如果您尝试对一个列表进行排序,该列表包含两个产生相同搜索键但不同且不可直接排序的项目,则该列表将崩溃
mylist = [{'score':50,'name':'bob'},{'score':50,'name':'linda'}]
mylist_annotated = [(x['score'], x) for x in mylist]
mylist_annotated.sort()
print( [x for key, x in mylist_annotated] )
将提供:
TypeError: '<' not supported between instances of 'dict' and 'dict'
我想如果您的数据中没有自然唯一的值,您可以在尝试排序之前插入一个值?也许是uuid
编辑:根据评论中的建议(谢谢!),您还可以使用operator.itemgetter:
import operator
mylist = [{'score':50,'name':'bob'},{'score':50,'name':'linda'}]
mylist_annotated = [(x['score'], x) for x in mylist]
mylist_annotated.sort(key=operator.itemgetter(0))
print( [x for key, x in mylist_annotated] )
通过将lambda
与async
生成器组合,可以模拟“async
lambda
”:
key=lambda x:(为uu'in'等待某个函数(x)。uuu anext_uu()
可以将()。\uuuu anext\uuuu()
移动到辅助对象,这可能会使模式更清晰:
def head(异步迭代器):返回异步迭代器。\uuuuanext\uuuu()
key=lambda x:head(等待函数(x)中的uu')
请注意,标准库中的排序方法/函数不是异步的。需要异步版本,例如(免责声明:我维护此库):
将asyncstdlib作为
mylist=wait a.sorted(mylist,key=lambda x:head(wait somefunction(x)表示uin'.'))
理解
lambda…:(…)。\uuuuuuanext\uuuu()
模式
一个“async
lambda
”将是一个匿名异步函数,或者换句话说,是一个匿名函数,其计算结果是一个可等待函数。这与async def
如何定义一个命名函数来计算一个可等待函数是并行的。任务可以分为两部分:匿名函数表达式和嵌套等待表达式
- 匿名函数表达式正是
的意思lambda…:…
- 等待的表情;然而:
- (异步)生成器表达式隐式创建(协同路由)函数。由于异步生成器只需要异步运行,因此可以在sync函数()中定义它
- 异步iterable可以通过its用作等待
async
lambda
”模式:
#|可调用和作用域的正则lambda
#| |异步作用域的异步生成器表达式
#第一项是值得期待的
key=lambda x:(为uu'中的uu'等待某个函数(x)。uuu anext_uu()
异步生成器中in'.的
只需进行一次迭代。任何至少有一次迭代的变体都可以。如果您已经定义了一个单独的异步函数,您可以进一步简化MisterMiyagi的答案:
mylist = await a.sorted(
mylist,
key=somefunction)
如果要在等待密钥后更改密钥,可以使用:
下面是一个完整的示例程序:
import asyncio
import asyncstdlib as a
async def some_function(x):
return x
async def testme():
mylist=[2, 1, 3]
mylist = await a.sorted(
mylist,
key=lambda x: a.apply(lambda after: 1 / after, some_function(x)))
print(f'mylist is: {mylist}')
if __name__ == "__main__":
asyncio.run(testme())
我得到了一个语法错误:理解中的'await'表达式不受支持
,因此我必须这样做(供将来参考):mylist_annotated=[]用于mylist中的x:mylist_annotated.append((wait some_function(x),x))mylist_annotated.sort()mylist=[x用于键,x用于mylist_annotated]现在它工作了,谢谢@没错,这是Python3.5中的一个限制,它在即将发布的Python3.6中被取消。发现了一个非常边缘的情况-请参阅我的答案:-)我认为这个边缘情况的最佳解决方案是将操作符.itemgetter(0)
作为排序()的关键函数传递给sort()
。元组按字典顺序排序,因此相等的键将导致第二项的比较。通过显式地只选择第一项作为排序键,我们可以防止第二次比较。
mylist = await a.sorted(
mylist,
key=lambda x: a.apply(lambda after: 1 / after, some_function(x)))
import asyncio
import asyncstdlib as a
async def some_function(x):
return x
async def testme():
mylist=[2, 1, 3]
mylist = await a.sorted(
mylist,
key=lambda x: a.apply(lambda after: 1 / after, some_function(x)))
print(f'mylist is: {mylist}')
if __name__ == "__main__":
asyncio.run(testme())