我想知道在Python中是否没有办法计算列表推导的补充。 类似的东西:
evens = [i in range(10) if i % 2 == 0]
odds = [i in range(10) if i % 2 != 0]
有没有办法在一次通话中获得平均值和赔率?对于一个非常大的列表,或者更昂贵的if语句,我认为这会节省很多时间。
答案 0 :(得分:4)
我相信之前已经问过这个问题,但我目前没有找到这个链接。
如果您尝试获取多个谓词并且只想在原始生成器上迭代一次,那么您将不得不使用简单的for
循环。
evens = []
odds = []
for i in xrange(10):
if i % 2 == 0: evens.append(i)
else: odds.append(i)
正如@dawg指出的那样,使用聪明的索引可以使循环内部的逻辑更简洁。
for i in xrange(10):
(evens,odds)[i%2].append(i)
答案 1 :(得分:1)
itertools.groupby
是我使用的。
In [1]: import itertools as it
In [2]: key = lambda i: i%2 == 0
In [3]: l = list(range(10))
In [4]: l.sort(key=key)
In [5]: [list(i[1]) for i in it.groupby(l, key=key)]
Out[5]: [[1, 3, 5, 7, 9], [0, 2, 4, 6, 8]]
答案 2 :(得分:0)
我会做以下其中一项:
evens = [i in range(10) if i % 2 == 0]
odds = [i in range(10) if i not in evens]
或者表现更好:
evens = [i in range(10) if i % 2 == 0]
evens_set = set(evens)
odds = [i in range(10) if i not in evens_set]
使用set
的效果会更好,因为not in
查询费用O(1)
而不是列表中的O(n)
答案 3 :(得分:0)
简而言之,您可以在一次通话中同时获得True和False案例,但您仍然需要将它们分成两个列表。你可以做到
range_10 = range(10)
odds = range_10[1::2]
evens = range_10[::2]
但这样做的好处可以忽略不计。 (事实上,你要创建三个列表而不是两个列表)。如果范围(10)的成本太高而无法创建两个列表,那么您只想这样做。
像我一样使用切片应该比使用测试和显式追加稍快一些。