Python - 使用try / exception和嵌套条件列表理解

时间:2013-12-31 19:40:27

标签: python python-2.7 try-catch list-comprehension conditional-statements

此代码应在O(n)线性时间内找到列表的模式。我想把它变成列表理解,因为我正在教自己Python,并且我正在努力提高我的列表理解能力。
这些都是提供信息的,但并没有真正回答我的问题:

Convert nested loops and conditions to a list comprehension

`elif` in list comprehension conditionals

Nested list comprehension equivalent

我遇到的问题是嵌套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]

但是我没有足够的胶带来修复语法错误的程度。

5 个答案:

答案 0 :(得分:6)

我知道你正在学习理解,但你也可以使用默认词典或计数器来做到这一点。

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]

答案 1 :(得分:2)

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

语法基本相同,只是使用parens而不是括号,所以你会这样做:

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

那就是说,你真的不想为你的特定应用做这件事。你想使用一个计数器:

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

答案 2 :(得分:1)

在列表补充中不可能使用try-except个表达式。

引用this answer

  

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

修改1:

您可以使用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 子句。

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

来自Python docs

  

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

编辑2:

这是我的列表comprenhension方法,效率不高,只是为了好玩:

{{1}}

答案 3 :(得分:1)

您无法将try: except:合并到列表理解中。但是,您可以通过重构为dict理解来解决这个问题:

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

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

答案 4 :(得分:0)

由于您尝试查找最常出现的值,因此使用max的一种简单方法是:

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

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