上下文是将整数列表拆分为它们自己的偶数和奇数列表。
even = []
odd = []
for i in my_list:
if i % 2 == 0:
even.append(i)
else:
odd.append(i)
有没有办法把上面的内容变成一个很好的、紧凑的列表理解..?
上下文是将整数列表拆分为它们自己的偶数和奇数列表。
even = []
odd = []
for i in my_list:
if i % 2 == 0:
even.append(i)
else:
odd.append(i)
有没有办法把上面的内容变成一个很好的、紧凑的列表理解..?
并非没有使用副作用并丢弃结果。你可以这样做:
even = []
odd = []
for i in my_list:
(odd if i % 2 else even).append(i)
这个问题通常称为对列表进行分区,您可以通过搜索 SO 找到一些解决方案,但没有一个更干净(在 Python 中)。
并非如此,您可以使用副作用来破解某些东西,但这不是列表推导的用途
>>> even = []
>>> odd = []
>>> [(odd if i%2 else even).append(i) for i in range(10)]
[None, None, None, None, None, None, None, None, None, None] # it's a waste to make this list
>>> even
[0, 2, 4, 6, 8]
>>> odd
[1, 3, 5, 7, 9]
稍微少一点浪费(但更难理解)是这样的
>>> even = []
>>> odd = [i for i in range(10) if i%2 or even.append(i)]
>>> even
[0, 2, 4, 6, 8]
>>> odd
[1, 3, 5, 7, 9]
但是,您可以使用第一个列表推导中的条件来简化循环
even = []
odd = []
for i in my_list: # Doesn't make a pointless list of `None`
(odd if i%2 else even).append(i)
如果my_list
真的很长,可能值得将附加方法绑定到局部变量以节省额外的查找(为 10000 个列表节省约 30%)
even = []
odd = []
even_append = even.append
odd_append = odd.append
for i in my_list:
(odd_append if i%2 else even_append)(i)
另一个加速是使用i&1
而不是i%2
选择偶数或奇数
如果奇数/偶数匹配列表索引,您可以使用切片来执行此操作:
>>> my_list=list(range(20))
>>> even,odd=my_list[0::2],my_list[1::2]
>>> even
[0, 2, 4, 6, 8, 10, 12, 14, 16, 18]
>>> odd
[1, 3, 5, 7, 9, 11, 13, 15, 17, 19]
如果您只想紧凑(且快速):
>>> isodd=lambda x: x%2
>>> random.shuffle(my_list)
>>> even,odd=[x for x in my_list if not isodd(x)],[x for x in my_list if isodd(x)]
>>> even
[12, 6, 2, 18, 14, 0, 10, 16, 8, 4]
>>> odd
[17, 1, 19, 11, 15, 5, 9, 13, 7, 3]
单程:
my_list=[i for i in range(50)]
lists=[[], []]
[ lists[x % 2].append(x) for x in my_list ]
print lists[0]
print lists[1]
不是世界上最短(或最好)的列表解析,但至少它没有副作用,它是以函数式编程风格编写的,没有使用append()
. 干得好:
lst = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
even, odd = [[x for x in y if x is not None] for y in zip(*((None, e) if e % 2 else (e, None) for e in lst))]
even
=> [2, 4, 6, 8, 10]
odd
=> [1, 3, 5, 7, 9]