在Python 3.4.2中,有没有办法让#34; if ...或......"列表理解中的陈述?
示例:
filtered_list = [x for x in other_list
if not ' ' in x or ' ' in other_list[int(other_list.index(x) -1)]]
#^item just before "x" in "other_list"
我知道这个命令不起作用。我知道这个也不是:
filtered_list = [x for x in other_list
if not (' ' in x) or (' ' in other_list[int(other_list.index(x) -1)])]
#^item just before "x" in "other_list"
有办法做到这一点吗? A" for"循环会更容易阅读,但我试图推动我对列表理解的理解。提前谢谢。
(奇怪的是,我无法在stackoverflow上找到像这样的先前问题。)
答案 0 :(得分:8)
您的代码确实完全按照您的要求执行操作(在简单情况下):
>>> other_list = ['foo', 'bar ', 'baz ']
>>> filtered_list = [x for x in other_list
... if not ' ' in x or ' ' in other_list[int(other_list.index(x) -1)]]
>>> print filtered_list
['foo', 'baz ']
即,它会选择所有不包含四个空格的项目,或者按照 包含四个空格的项目。
这在很多方面都是非常奇怪的代码 - 例如,为什么使用.index
会在重复的情况下选择第一个项等于x
;并且,如果第一个项目被认为是“跟随”最后一个项目,正如此代码所说的那样?但是,如果没有用英语清楚地解释你的代码应该完成什么,只需对代码进行“逆向工程”,它就像在简单的情况下完全一样(第一项不包含四个空格,没有重复) ),虽然非常,非常效率低(O(N平方),其中使用enumerate
将O(N)变得非常简单。
所以请提供一个清晰,详尽的解释,说明你认为你在这里做了什么,我很乐意编辑这个答案,告诉你如何做你真正的意思,而不是什么你(显然是错误的)编码。但是,我无法读懂你的想法,所以......(顺便说一句,这确实需要“回答”,因为格式化上面的代码对于它的可读性至关重要,所以它不能只是“只是一个评论”)。
已添加:“在other_list
之前获取当前项目的正常方式”当然不使用.index
(O(N)
所以使整个列表理解O(N squared)
!)而是enumerate
。什么是“之前的项目”第一个需要解释,但正常的读数是“没有这样的东西”。
假设您有两个函数curp
(谓词限定当前项目,如果它是真实的)和prevp
(谓词限定当前项目,如果在上一个 item if any )。然后,从列表xs
中选择项目的常规方法显然是:
[x for i, x in enumerate(xs) if curp(x) or i>0 and prevp(xs[i-1])]
当然,无论谓词是否被优雅地封装到函数中,如上所述,还是更粗略地以线性表达,它的工作原理完全相同。所以,如果,例如:
def curp(x): return 'AB' not in x
def prevp(xp): return 'CD' in xp
然后下面的listcomp等同于前一个,只是不太可读:
[x for i, x in enumerate(xs) if 'AB' not in X or i>0 and 'CD' in xs[i-1]]
圆括号在这里是相当多余的,而not 'AB' in X
是一种更不优雅,可读和明确的表达'AB' not in X
的方式 - 但是,可以随意忽略这些风格的意见,它们只来自15毕竟,多年的Python体验: - )
答案 1 :(得分:2)
您可以使用多个and
s / or
,但只能使用一个if
。例如,以下内容:
In [7]: a = [1,2,3,4,5,6,7,8,9,10]
In [8]: b = [x for x in a if x % 2 == 0 or x % 3 == 0]
In [9]: b
Out[9]: [2, 3, 4, 6, 8, 9, 10]
工作正常。
答案 2 :(得分:0)
我希望这能解决你的问题:
other_list = ['foo', 'bar ', 'baz ']
filtered_list = [x for x in other_list if (' ' not in x) or (' ' not in other_list[int(other_list.index(x) -1)])]
print filtered_list
注意:该位置不确定如何解释命令。我以为你想要这样的东西。
答案 3 :(得分:0)
Yikes我刚刚意识到我的错误写了我的例子。我想切换if和for语句:
filtered_list = [x
if not ' ' in x or ' ' in other_list[int(other_list.index(x) -1)]
for x in other_list]
我会发布我的整个列表理解,以便按照这个顺序显示我为什么要这样做。基本上,我有一个包含一些缩进项目的列表。对于每个缩进项目,我想将其缩进加倍并在其前缩进项目,同时保持列表中其余项目不变。
indented_list = [t
if not ' ' in t or ' ' in stripped_list[int(stripped_list.index(t) + 1)]
else ''.join((' ', t))
if not t[0].isdigit()
else re.sub(r'^(\d)(.*)', r'\1\2 \3',
stripped_list[int(stripped_list.index(t))])
if not t[1].isdigit()
else re.sub(r'^(\d)(\d)(.*)', r'\1\2 \3',
stripped_list[int(stripped_list.index(t))])
for t in stripped_list]
我知道可能更容易实现这一目标。几周前我才开始学习编程。