社区所有版块导航
Python
python开源   Django   Python   DjangoApp   pycharm  
DATA
docker   Elasticsearch  
aigc
aigc   chatgpt  
WEB开发
linux   MongoDB   Redis   DATABASE   NGINX   其他Web框架   web工具   zookeeper   tornado   NoSql   Bootstrap   js   peewee   Git   bottle   IE   MQ   Jquery  
机器学习
机器学习算法  
Python88.com
反馈   公告   社区推广  
产品
短视频  
印度
印度  
Py学习  »  Python

在python的[]中使用break或continue会产生错误[duplicate]

一笑奈何 • 5 年前 • 1939 次点击  

我如何根据一个条件打破列表理解,例如 412 找到了吗?

代码:

numbers = [951, 402, 984, 651, 360, 69, 408, 319, 601, 485, 980, 507, 725, 547, 544,
           615, 83, 165, 141, 501, 263, 617, 865, 575, 219, 390, 984, 592, 236, 105, 942, 941,
           386, 462, 47, 418, 907, 344, 236, 375, 823, 566, 597, 978, 328, 615, 953, 345, 399,
           162, 758, 219, 918, 237, 412, 566, 826, 248, 866, 950, 626, 949, 687, 217, 815, 67,
           104, 58, 512, 24, 892, 894, 767, 553, 81, 379, 843, 831, 445, 742, 717, 958, 609, 842,
           451, 688, 753, 854, 685, 93, 857, 440, 380, 126, 721, 328, 753, 470, 743, 527]

even = [n for n in numbers if 0 == n % 2]

所以从功能上来说,你可以推断这是应该做的:

even = [n for n in numbers if 0 == n % 2 and break if n == 412]

真正地 首选:

  • 一行字
  • 如果可能的话,没有像itertools这样的高级库,“纯python”(阅读:解决方案不应该使用任何 import 声明或类似)
Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/47039
 
1939 次点击  
文章 [ 7 ]  |  最新文章 5 年前
recnac
Reply   •   1 楼
recnac    6 年前

另一个偷偷摸摸的单线解决方案 breaking in list comprehension ,借助于 end 条件。

不使用 numbers.index(412) ,可能快一点?

even = [n for end in [[]] for n in numbers
        if (False if end or n != 412 else end.append(42))
        or not end and not n % 2]

注:这是个坏主意。 只是为了好玩:)

正如@wolframh所说:

对于那些抱怨它是黑客的,不应该在生产代码中使用:嗯,你是对的。 一定地。

Marcin
Reply   •   2 楼
Marcin    13 年前

列表显示(包括列表理解)的语法如下: http://docs.python.org/reference/expressions.html#list-displays

如你所见,没有什么特别的 while until 语法。最接近的是:

even_numbers = (n for n in numbers if 0 == n % 2)
list(itertools.takewhile(lambda x: x != 412, even_numbers))

(代码取自sven marnach的答案,在我输入这个时发布)。

Anil_M
Reply   •   3 楼
Anil_M    7 年前

我知道这是一个很老的帖子,但是自从op问起 break 在一个 list-comprehension 我也在寻找类似的东西,我想我会把我的发现贴在这里,以备将来参考。

在调查的时候 打破 ,我偶然发现了 iter 作为 iter(callable, sentinel) 返回一个迭代器 “中断” 一次可调用的迭代 function 值等于 sentinel 价值。

>>> help(iter)
Help on built-in function iter in module __builtin__:

iter(...)
    iter(collection) -> iterator
    iter(callable, sentinel) -> iterator

    Get an iterator from an object.  In the first form, the argument must
    supply its own iterator, or be a sequence.
    In the second form, the callable is called until it returns the sentinel.

这里棘手的部分是定义一个适合给定问题的函数。在这种情况下,首先我们需要转换给定的 list 属于 numbers 给一个 iterator 使用 x = iter(numbers) 作为外部变量输入到 lambda 功能。

接下来,我们的可调用函数只是调用迭代器来输出下一个值。迭代器然后与我们的sentinel值(在本例中为412)进行比较,一旦达到该值,就“中断”。

print [i for i in iter(lambda x=iter(numbers): next(x),412) if i %2 == 0]

>>> 
[402, 984, 360, 408, 980, 544, 390, 984, 592, 236, 942, 386, 462, 418,  
 344, 236, 566, 978, 328, 162, 758, 918]
Andrew Clark
Reply   •   4 楼
Andrew Clark    13 年前

如果412肯定会在名单上,你可以用这个:

even = [n for n in numbers[:numbers.index(412)] if not n % 2]

如果要在结果中包含412,请使用 numbers[:numbers.index(412)+1] 为了切片。

注意,由于切片的原因,这将比itertools或for循环解决方案效率低(至少在内存方面)。

Sven Marnach
Reply   •   5 楼
Sven Marnach    13 年前

可以将生成器表达式与 itertools.takewhile() 以下内容:

even_numbers = (n for n in numbers if not n % 2)
list(itertools.takewhile(lambda x: x != 412, even_numbers))

编辑 :我刚刚注意到不使用任何 import 好吧,我还是把这个答案留在这里。

WolframH
Reply   •   6 楼
WolframH    13 年前

使用函数来提升 StopIteration list 要抓住它:

>>> def end_of_loop():
...     raise StopIteration
... 
>>> even = list(end_of_loop() if n == 412 else n for n in numbers if 0 == n % 2)
>>> print(even)
[402, 984, 360, 408, 980, 544, 390, 984, 592, 236, 942, 386, 462, 418, 344, 236, 566, 978, 328, 162, 758, 918]

对于那些抱怨的人来说,这不是一句空话:

even = list(next(iter(())) if n == 412 else n for n in numbers if 0 == n % 2)

对于那些抱怨它是黑客的,不应该在生产代码中使用:嗯,你是对的。 一定地。

Michael David Watson
Reply   •   7 楼
Michael David Watson    10 年前
even = [n for n in numbers[:None if 412 not in numbers else numbers.index(412)] if not n % 2] 

只是取了上面F.J.的代码,添加了一个三值来检查412是否在列表中。仍然是一个'一行',将工作,即使412不在名单上。