Python 列表理解中的临时变量

Python 列表理解中的临时变量,python,list-comprehension,Python,List Comprehension,我经常遇到这样一段代码 raw_data = [(s.split(',')[0], s.split(',')[1]) for s in all_lines if s.split(',')[1] != '"NaN"'] 基本上,我想知道是否有办法创建一个临时变量,如splitted_s,以避免在循环对象上重复操作(例如,在本例中,必须将其拆分三次) 如果有两个操作要处理,可以嵌入另一个列表: raw_data = [(lhs, rhs) for lhs, rhs

我经常遇到这样一段代码

raw_data  = [(s.split(',')[0], s.split(',')[1]) for s in all_lines if s.split(',')[1] != '"NaN"']

基本上,我想知道是否有办法创建一个临时变量,如
splitted_s
,以避免在循环对象上重复操作(例如,在本例中,必须将其拆分三次)

如果有两个操作要处理,可以嵌入另一个列表:

raw_data  = [(lhs, rhs) 
            for lhs, rhs 
            in [s.split(',')[:2] for s in all_lines]
            if rhs != '"NaN"']
您可以在内部使用generator(它也提供了一个小的性能增益):

它甚至比您的实现更快:

import timeit

setup = '''import random, string;
all_lines = [','.join((random.choice(string.letters),
                    str(random.random() if random.random() > 0.3 else '"NaN"')))
                    for i in range(10000)]'''
oneloop = '''[(s.split(',')[0], s.split(',')[1]) 
              for s in all_lines if s.split(',')[1] != '"NaN"']'''
twoloops = '''raw_data  = [(lhs, rhs) 
                for lhs, rhs 
                in [s.split(',') for s in all_lines]
                if rhs != '"NaN"']'''

timeit.timeit(oneloop, setup, number=1000)  # 7.77 secs
timeit.timeit(twoloops, setup, number=1000) # 4.68 secs
你不能

列表理解由括号组成,括号中包含表达式,后跟for子句,然后是零个或多个for或if子句。结果将是一个新的列表,该列表是在其后的for和if子句上下文中对表达式求值的结果

Python中的赋值不是表达式


正如Padraic Cunningham评论的那样-如果需要多次拆分,不要在列表理解中执行此操作。

启动
Python 3.8
,并引入(
:=
运算符),可以在列表理解中使用局部变量,以避免调用两次相同的表达式:

在我们的例子中,如果
parts[1]
不等于
NaN,我们可以将
line.split(',')
的求值命名为变量
parts
,同时使用表达式的结果过滤列表;从而重复使用
零件
生成映射值:

# lines = ['1,2,3,4', '5,NaN,7,8']
[(parts[0], parts[1]) for line in lines if (parts := line.split(','))[1] != 'NaN']
# [('1', '2')]

lambda
功能?可能是这样的:
temp=lambda x,i:x.split(',')[i]
你可以将它直接滚动到列表中,如果s[1]!=“Nan”]
必须将同一个字符串拆分三次,我将不使用理解,这只在
split
生成两个项目时有效。此外,内部列表理解可能是一个生成器。@tobias_k:我已经更新了我的答案。说到发电机,在我的测试中它给了我4.49秒;)尝试
s.split(',',2)
您不能在列表comp中分配,当然,但您肯定可以在内部使用
splitted_
,例如使用
在地图中为splitted_(lambda x:x.split(','),所有_行)
。如果没有“if”条件,该怎么办;有没有办法仍然分配给临时变量?@ElRudi我不确定你指的是什么临时变量,但是任何表达式都可以分配给变量,不管它是否是条件的一部分。谢谢你的快速回复。我的意思是,在你的回答中,你将
line.split(',')
分配给(我称之为“临时变量”)
部分,你这样做是作为理解中
if
条件的一部分。然后可以重用元组中的
部分。如果不存在此类if条件,是否可以对
零件进行相同的赋值?所以,当最初的问题是重写
原始数据=[(s.split(',')[0],s.split(',')[1])用于所有行中的s]
@ElRudi哦,我明白了,是的,你可以这样做:
[(parts:=line.split(',')[0],parts[1])用于行中的行]
。感觉读起来有点困难,if条件下的赋值使它更清晰。
# lines = ['1,2,3,4', '5,NaN,7,8']
[(parts[0], parts[1]) for line in lines if (parts := line.split(','))[1] != 'NaN']
# [('1', '2')]