到目前为止,我没有找到按特定条件拆分列表的便捷方法,例如,我有一个记录列表:
a = ((0,1),(1,0),(0,2),(1,0),(3,0),(4,0),(0,3),(1,5)....)
我想将内容拆分为2个列表
alist = []
blist = []
for x in a:
if x[0] == 0:
alist.append(x)
elif x[0] == 1:
blist.append(x)
不是很简洁。
写成列表推导:
aList = [x for x in a if x[0] == 0]
bList = [x for x in a if x[0] == 1]
列表推导通常适用于阅读和表现,但在这种情况下,列表必须重复两次。
有没有更好的方法来完成这项工作?
答案 0 :(得分:6)
嗯,条件不同,难怪你需要两个循环。但如果你想牺牲一些可读性,
aList, bList = [[x for x in a if x[0] == i] for i in (0, 1)]
答案 1 :(得分:6)
添加一行将使循环更加简洁,代价是可读性(和FPness)。
alist = []
blist = []
bothlists = [alist, blist]
for x in a:
bothlists[x[0]].append(x)
答案 2 :(得分:1)
如果你真的想让事情变得复杂,你可以从itertools
导入一些函数来混淆你的可读解决方案:
from operator import itemgetter
from collections import defaultdict
d = defaultdict(list)
for key, value in itertools.groupby(a, itemgetter(0)):
d[key].append(list(value))
这是输出:
>>> print d[0]
[[(0, 1)], [(0, 2)], [(0, 3)]]
>>> print d[1]
[[(1, 0)], [(1, 0)], [(1, 5)]]
>>> print d[4]
[[(4, 0)]]
此代码仅使用第一个元组中的值作为键将项目分组到字典中。它比你的代码更通用。
答案 3 :(得分:0)
我会使用filter
,请参阅:http://docs.python.org/2/library/functions.html#filter
>>> a = ((0,1), (1,0), (0,2), (1,0), (3,0), (4,0), (0,3), (1,5))
>>> filter(lambda x: x[0] == 1, a)
((1, 0), (1, 0), (1, 5))
为避免冗余代码,您可以在迭代中收集条件,如下所示:
>>> fs = (lambda x: x[0] == 0, lambda x: x[0] == 1)
>>> for f in fs:
... filter(f, a)
...
((0, 1), (0, 2), (0, 3))
((1, 0), (1, 0), (1, 5))
答案 4 :(得分:0)
字典可以更简洁。
alist, blist = [], []
for x in a:
{0: alist, 1: blist}.get(x[0]).append(x)
这是一种灵活的模式,您可以扩展以涵盖其他情况。
例如,您可以添加更多选择。您还可以通过将 .get(x[0])
更改为 .get(x[0], [])
来优雅地处理意外值。