[英]How to compose a list with conditional elements
我用 python 编程了一段时间,我发现这种语言对程序员非常友好,所以也许有一种技术我不知道如何用条件元素组合一个列表。 简化的例子是:
# in pseudo code
add_two = True
my_list = [
"one",
"two" if add_two,
"three",
]
基本上,我正在寻找一种方便的方法来创建一个列表,其中包含在某些特定条件下添加的一些内容。
一些看起来不太好的替代方案:
add_two = True
# option 1
my_list = []
my_list += ["one"]
my_list += ["two"] if add_two else []
my_list += ["three"]
# option 2
my_list = []
my_list += ["one"]
if add_two: my_list += ["two"]
my_list += ["three"]
有什么可以简化它吗? 干杯!
如果您可以创建一个 bool 列表来表示您希望从候选列表中保留哪些元素,那么您可以非常简洁地完成此操作。 例如:
candidates = ['one', 'two', 'three', 'four', 'five']
include = [True, True, False, True, False]
result = [c for c, i in zip(candidates, include) if i]
print(result)
# ['one', 'two', 'four']
如果您可以使用 numpy,这将变得更加简洁:
import numpy as np
candidates = np.array(['one', 'two', 'three', 'four', 'five'])
include = [True, True, False, True, False]
print(candidates[include]) # can use boolean indexing directly!
# ['one', 'two', 'four']
最后,正如评论中所建议的,您可以使用itertools.compress()
。 请注意,这将返回一个迭代器,因此您必须对其进行解包。
from itertools import compress
print([v for v in compress(candidates, include)])
# ['one', 'two', 'four']
在一行中你可以写:
my_list = ['one'] + (['two'] if add_two else []) + ['three']
或者使用列表理解:
my_list = [x for x in ('one', 'two' if add_two else '', 'three') if x]
或者删除假值的功能方法:
my_list = list(filter(None, ('one', 'two' if add_two else '', 'three')))
首先,我会编写一个简单的谓词函数来确定是否应该包含一个值。 让我们假设在这个整数列表中,您只想包含那些>0
数字。
def is_strictly_positive(x):
return x > 0
然后你就可以得到完整的数字列表:
lst = [-3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7]
并过滤它们:
filter(is_strictly_positive, lst) # 1 2 3 4 5 6 7
它创建了一个filter
对象——一个生成你一次需要的值的生成器。 如果你需要一个完整的列表,你可以这样做:
new_lst = list(filter(is_strictly_positive, lst)) # [1, 2, 3, 4, 5, 6, 7]
或者,惯用地,使用列表理解
new_lst = [x for x in lst if is_strictly_positive(x)] # [1, 2, 3, 4, 5, 6, 7]
您还可以使用itertools.compress
产生与filter
类似的结果,但在这个简单的情况下它有点过度设计。
new_lst_gen = itertools.compress(lst, map(is_strictly_positive, lst)) # 1 2 3 4 5 6 7
这种方法使用None
标记值来删除值,然后在最后将它们过滤掉。 如果您的数据已经包含None
,您可以创建另一个哨兵对象来代替。
add_two = True
my_list = [
"one",
"two" if add_two else None,
"three",
]
my_list = [e for e in my_list if e is not None]
print(my_list)
# ['one', 'two', 'three']
itertools
模块有很多有用的功能:
from itertools import compress, dropwhile, takewhile, filterfalse
condition1 = True
condition2 = False
condition3 = True
l = list(range(10))
print(list(compress(['a', 'b', 'c'], [condition1, condition2, condition3])))
# ['a', 'c']
print(list(dropwhile(lambda x: x > 5, l)))
# [5, 6, 7, 8, 9]
print(list(takewhile(lambda x: x < 5, l)))
# [0, 1, 2, 3, 4]
print(list(filterfalse(lambda x: x % 2, l))) # returns elements whose predicates == False
# [0, 2, 4, 6, 8]
另一种单行方法,在我看来更 Pythonic,是:
add_two = True
my_list = ['one'] + ['two'] * add_two + ['three']
如果有多个条件元素,我认为应该使用其他替代方法,例如 bool 列表。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.