有没有更好的方法来做复杂的'列表理解?

时间:2018-05-05 06:40:47

标签: python performance format list-comprehension

我倾向于在Python中大量使用列表理解,因为我认为它是一种生成列表的简洁方法,但我常常发现自己一周后回来并自言自语"到底是做什么的我这样做是为了?!" ,它是一个70多个字符的嵌套条件列表理解语句。我想知道如果我应该将其分解为if / elif / else,以及性能影响(如果有的话),它是否达到某一点。

我目前的情况:

来自call的返回结构是一个元组列表。我需要将它转换为列表,需要清理一些值,我需要从列表中删除最后一个元素。

e.g。

[(val1, ' ', 'ChangeMe', 'RemoveMe),
 (val1, ' ', 'ChangeMe', 'RemoveMe),
 (val1, ' ', 'ChangeMe', 'RemoveMe)]

因此,在这种情况下,我想删除RemoveMe,将所有' '替换为'',并将ChangeMe替换为val2。我知道这是一个很大的变化,但我回来的数据有时很糟糕,我无法控制作为回应的对象。

我目前有类似的东西:

response = cursor.fetchall()
response = [['' if item == ' ' else item if item != 'ChangeMe' else 'val2' for item in row][:-1] for row in response]`

嵌套的多条件理解语句是否令人不悦?我知道风格上Python更喜欢非常易读,但也很紧凑,而不是冗长。

任何提示或信息都将不胜感激。谢谢大家!

2 个答案:

答案 0 :(得分:5)

Python赞成单行,唯一的条件是这些使代码更具可读性,而不是让它复杂化。

在这种情况下,你使用两个嵌套列表理解,两个相邻的三元运算符,一个列表切片,所有这一切都在一行超过100个字符......这是一切都是可读的。

有时使用经典的for循环会更好。

result = []
for val, space, item, remove in response:
    result.append([val, '', 'val2'])

然后你意识到你可以把它写成列表理解更容易理解(假设你的过滤条件很简单):

result = [[val, '', 'val2'] for val, *_ in response]

请记住,每个代码一次编写,但多次阅读

答案 1 :(得分:0)

这是一种快速的方法,您可以使用字典来映射项目进行列表理解:

response = [('val1', ' ', 'ChangeMe', 'RemoveMe'), ('val1', ' ', 'ChangeMe', 'RemoveMe'), ('val1', ' ', 'ChangeMe', 'RemoveMe')]
map_dict = {' ': '', 'ChangeMe': 'val2', 'val1': 'val1'}

response = [tuple(map_dict[x] for x in tupl if x != 'RemoveMe') for tupl in response]
# [('val1', '', 'val2'), ('val1', '', 'val2'), ('val1', '', 'val2')]