繁体   English   中英

Python —具有try / exception和嵌套条件的列表理解

[英]Python — list comprehension with try/exception and nested conditional

此代码应以O(n)线性时间找到列表的模式。 我想将其转换为列表理解,因为我正在自学Python,并试图提高列表理解能力。
这些内容翔实,但并不能真正回答我的问题:

将嵌套循环和条件转换为列表理解

清单理解条件中的`elif`

嵌套列表理解等价

我遇到的问题是嵌套if和try / except。 我确定这是一个简单的问题,所以初级Python程序员可能很快就能找到答案。

def mode(L):
    # your code here
    d = {}; mode = 0; freq = 0
    for j in L:
        try:
            d[j] += 1
            if d[j] > freq:
                mode = j; freq = d[j]
        except(KeyError): d[j] = 1
    return mode

请注意, L参数是一个如下的整数列表:

L = [3,4,1,20,102,3,5,67,39,10,1,4,34,1,6,107,99]

我在想类似的东西:

[try (d[j] += 1) if d[j] > freq (mode = j; freq = d[j]) except(KeyError): d[j] = 1 for j in L]

但是我没有足够的胶带来固定语法对这件事的影响。

我知道您正在学习理解,但是您可以使用默认字典或Counter来完成。

import collections
def mode(L):
    # your code here
    d = collections.defaultdict(lambda: 1); mode = 0; freq = 0
    for j in L:
            d[j] += 1
            if d[j] > freq:
                mode = j; freq = d[j]
    return mode

更好的是,当您不尝试学习理解力时:

import collections
def mode(L):
    collections.Counter(L).most_common(1)[0][0]

尽管可能无法直接在列表理解中执行此操作,但是也没有理由这样做。 您实际上只想在实际检索结果时检查错误。 因此,您确实想使用generator而不是列表推导。

语法大致相同,只是使用括号而不是括号,因此您将执行以下操作:

generator = (do something)
try:
    for thing in generator
except KeyError:
   etc...

就是说,您确实不想为您的特定应用程序执行此操作。 您要使用一个计数器:

from collections import Counter
d = Counter(L)
mode = Counter.most_common(1)[0]

在列表理解中不能使用try-except表达式。

引用此答案

列表理解中的异常是不可能处理的,因为列表理解是一个包含其他表达式的表达式,仅此而已(即没有语句,只有语句可以捕获/忽略/处理异常)。

编辑1:

try-except使用try-except子句try-except ,您可以做的是使用字典中的get方法:

def mode(L):
    d = {}
    mode = 0
    freq = 0
    for j in L:
        d[j] = d.get(j, 0) + 1
        if d[j] > freq:
            mode = j
            freq = d[j]
    return mode

Python文档

get(key [,default]) :如果key在字典中,则返回key的值,否则返回default。 如果未提供default,则默认为None,因此此方法永远不会引发KeyError。

编辑2:

这是我的列表理解方法,不是很有效,只是为了好玩:

r2 = max(zip(L, [L.count(e) for e in L]), key = lambda x: x[1])[0]

您不能将try: except:纳入列表理解中。 但是,您可以通过重构为dict理解来解决它:

d = {i: L.count(i) for i in L}

然后,您可以在单独的测试中确定最大密钥和相应密钥。 但是,这将是O(n**2)

由于您尝试查找最常出现的值,因此使用max可以轻松实现这一目的:

def mode(L):
   return max(L, key=L.count)

这比其他建议使用collections.Counter答案效率低(它是O(N^2)而不是O(N) ),但是对于中等大小的列表,它可能足够快。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM