Python列表推导式(if,continue,break)

8

我试图养成创建列表推导式的习惯,基本上优化我写的任何代码。我做了个小练习,以查找给定数字中是否所有数字都是偶数为例,当尝试使用for循环和if语句创建列表时,我遇到了“continue”和“break”的问题。我能把这些流控制插入到列表中吗?

我想知道我能缩短任何代码的程度。这是我写的内容,我很想听听你们的反馈。

numbers = [str(x) for x in range(0, 10000)]

def is_all_even(nums):
    temp_lst = []
    evens_lst = []
    for x in nums:
        for y in x:
            if int(y) % 2 == 0:
                temp_lst.append(str(y))
                continue
            else:
                break
        if len(''.join(temp_lst[:])) == len(x):
            evens_lst.append(''.join(temp_lst[:]))
        del temp_lst[:]
    print(evens_lst)

11
如果你的代码已经可以运行,并且你有兴趣改进它,可以到Code Review上尝试一下。 - Kevin
2
通常来说,列表推导式是高阶函数mapfilter的有效实现。虽然许多循环可以重写成列表推导式,但它们并不真正意味着要取代for循环。在mapfilter的上下文中,breakcontinue的概念并不真正有意义,因此您不能在推导式中包含它们。 - aruisdante
1
@aruisdante: “它们并不是for循环的替代品”…这可能是不正确的。列表推导式在生成表达式列表时非常高效。与显式循环相比,您通常需要将元素附加到列表中,这并不那么高效。此外,列表推导式通常可以被制定为生成器,从而减少了中间列表的开销。 - Abhijit
1
你应该将代码拆分为两个函数:一个函数用于判断数字是否为“全偶数”,另一个函数用于管理列表;使用列表推导式与否是次要问题。 - Don
1
@Abhijit:这是Python中应该避免的微观优化,除非你已经通过cProfile运行并验证它确实存在问题。在那之前,你应该只写最清晰的代码。 - Kevin
显示剩余4条评论
3个回答

11

您可以使用列表推导式,使用all函数查找包含所有偶数数字的数字:

print([s for s in numbers if all(not int(ch) % 2 for ch in s)])

all会在发现任何奇数数字时进行短路。

如果你不想一次性将所有数字存储在内存中,可以使用生成器表达式

evens = (s for s in numbers if all(not int(ch) % 2 for ch in s))

要访问这些数字,只需要遍历偶数:

for n in evens:
    print(n)

你也可以在Python 3中使用filter进行函数式编程,它返回一个迭代器:

In [5]: evens = filter(lambda x: all(not int(ch) % 2 for ch in x), numbers)

In [6]: next(evens)
Out[6]: '0'

In [7]: next(evens)
Out[7]: '2'

In [8]: next(evens)
Out[8]: '4'

In [9]: next(evens)
Out[9]: '6'

1
根据 OP 的需求,他们可能需要一个生成器表达式。 - Kevin
由于我们使用的是Python 3,您可以使用print(*evens, sep='\n')打印。 - TigerhawkT3
@TigerhawkT3,如果OP想要使用这些值,他们需要迭代偶数,如果你只想打印,你也可以在Python 2中使用str.join。 - Padraic Cunningham
是的,这适用于已经保存了“evens”的情况。for x in iterable: print(x)print(*iterable, sep='\n')具有相同的结果。 - TigerhawkT3

5
[x for x in range(10000) if all(c in '02468' for c in str(x))]

3

不必将整个数字列表发送到函数中,您只需向函数发送一个数字,然后使用列表推导式将其应用于您的列表。

def is_all_even(num):
    return all(ch in '02468' for ch in str(num))

print([n for n in range(10000) if is_all_even(n)])

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接