是否有一种简洁的方法将以下代码片段重写为列表理解?
nsms = []
for line in lines:
fields = line.split(';')
if len(fields) > 4 and fields[4] == 'NSM':
nsms += [fields]
挑战是临时变量
fields
。 如果没有它,推导式必须每行调用 split
(最多)三次:
nsms = [line.split(';')
for line in lines
if len(line.split(';')) > 4 and line.split(';')[4] == 'NSM']
我并不担心冗余调用的低效率,而是担心它们对代码表达能力的影响以及打字错误风险的增加。
我想也许
with
可以帮助:
# My failed attempt
nsms = [fields
for line in lines
with fields = line.split(';')
if len(fields) > 4 and fields[4] == 'NSM']
(我发现相当令人惊讶的是,这会因缩进错误而失败。我的其他尝试导致语法错误指向
with
。)
据我所知,for 循环是将本地临时变量引入列表理解的唯一方法,因此可能的黑客方法是“迭代”一个项目的列表,如下所示:
nsms = [fields
for line in lines
for fields in [line.split(';')]
if len(fields) > 4 and fields[4] == 'NSM']
这是可行的,但是有没有办法在不将临时变量伪装成循环归纳变量的情况下做到这一点?
在上面的示例中,
lines
是文本文件中包含分号分隔值的行列表。 具体来说,来自 UnicodeData.txt 的副本:
with open('UnicodeData.txt', 'r') as source:
lines = source.readlines()
这相当简单。您可以在包含
for
返回的列表的单例元组的列表理解中使用 line.split(';')
子句。
nsms = [
fields
for line in lines
for fields in (line.split(';'),)
if len(fields) > 4 and fields[4] == 'NSM'
]
这应该有效:
nsms = [fields for fields in (line.split(';') for line in lines)
if len(fields) > 4 and fields[4] == 'NSM']