我正在尝试从一个主列表创建几个新列表,其中新列表包含来自主列表的类似项目。具体来说,我有一份巴士路线清单。这是一个示例数据集:
[u'Bus04_00_00_IB_pts_Line', u'Bus04_00_00_OB_pts_Line', u'Bus15_00_00_IB_pts_Line', u'Bus15_00_00_OB_pts_Line']
大多数公交线路有一个入站(IB)和一个出站(OB)项目(有些有多个IB和OB,有些只有一条路由,b / c它们是循环路由)。最后,我想在地图软件中合并IB和OB路线(我已经知道该怎么做了)......
我最初创建了文件名,因此前5个字符代表总线路径,无论它是IB还是OB。因此,我可以根据前5个字符对相似的项目进行分组。例如,当我写:
for route in routes:
print route[0:5]
我明白了:
>>>
Bus04
Bus04
Bus15
Bus15
如何将与Bus04
和Bus04
以及Bus15
和Bus15
相关的文件“分组”到新列表中,以便我得到:
[u'Bus04_00_00_IB_pts_Line', u'Bus04_00_00_OB_pts_Line']
和[u'Bus15_00_00_IB_pts_Line', u'Bus15_00_00_OB_pts_Line']
作为单独的列表?
我正在考虑循环遍历每个项目的内容,查看每个项目的前五个字符,然后创建一个新列表,每个新的五个字符项出现(并将该项添加到新列表)或检查列表是否已存在并将类似项附加到其中。
我很难在代码中写出来,所以非常感谢任何帮助!
答案 0 :(得分:6)
import collections
L = [u'Bus04_00_00_IB_pts_Line', u'Bus04_00_00_OB_pts_Line', u'Bus15_00_00_IB_pts_Line', u'Bus15_00_00_OB_pts_Line']
d = collections.defaultdict(list)
for elem in L:
d[elem.split('_')[0]].append(elem)
print(dict(d))
这会产生:
{u'Bus04': [u'Bus04_00_00_IB_pts_Line', u'Bus04_00_00_OB_pts_Line'],
u'Bus15': [u'Bus15_00_00_IB_pts_Line', u'Bus15_00_00_OB_pts_Line']}
与目前提出的其他一些解决方案不同,无论条目在输入列表中的显示顺序如何,这都有效。
答案 1 :(得分:3)
您可以将itertools.groupby
与自定义键功能结合使用,例如lambda x: x[0:5]
。
这是一个演示,为您提供静态列表(即不仅仅是生成器):
>>> import itertools
>>> lst = [u'Bus04_00_00_IB_pts_Line', u'Bus04_00_00_OB_pts_Line', u'Bus15_00_00_IB_pts_Line', u'Bus15_00_00_OB_pts_Line']
>>> [(key, list(val)) for key, val in itertools.groupby(lst, lambda x: x[0:5])]
Out[9]:
[(u'Bus04', [u'Bus04_00_00_IB_pts_Line', u'Bus04_00_00_OB_pts_Line']),
(u'Bus15', [u'Bus15_00_00_IB_pts_Line', u'Bus15_00_00_OB_pts_Line'])]
答案 2 :(得分:2)
import collections
lists = collections.defaultdict(list)
for item in masterlist:
lists[item[:5]].append(item)
答案 3 :(得分:1)
您可以将groupby与lambda键功能配合使用。
from itertools import groupby
results = groupby(data, key=lambda x: x[0:5])
>>> for item, values in results:
>>> print item, list(values)
Bus04 [u'Bus04_00_00_IB_pts_Line', u'Bus04_00_00_OB_pts_Line']
Bus15 [u'Bus15_00_00_IB_pts_Line', u'Bus15_00_00_OB_pts_Line']
正如NPE在他的解决方案中所提到的,原始列表必须是一个排序列表。
但是,如果你只需要一次处理一个条目,这个解决方案非常有效,因为生成器只生成一个值,然后等待下一个值准备好使用。