4

我正在尝试从一个主列表创建几个新列表,其中新列表包含主列表中的类似项目。具体来说,我有一个巴士路线列表。这是一个示例数据集:

[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

如何将与Bus04andBus04Bus15and相关的文件“分组”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']作为单独的列表?

我正在考虑循环遍历每个项目,查看每个项目的前五个字符,然后使用出现的每个新的五个字符项目创建一个新列表(并将该项目添加到新列表中)或检查是否一个列表已经存在并将类似的项目附加到它。

我很难用代码写出来,所以非常感谢任何帮助!

4

4 回答 4

6

我会用collections.defaultdict这个:

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']}

与迄今为止提出的一些其他解决方案不同,这与条目在输入列表中出现的顺序无关。

于 2012-12-20T17:37:58.603 回答
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'])]
于 2012-12-20T17:37:43.980 回答
2
import collections

lists = collections.defaultdict(list)
for item in masterlist:
    lists[item[:5]].append(item)
于 2012-12-20T17:37:50.720 回答
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 在他的解决方案中提到的,原始列表必须是排序列表。

但是,如果您一次只需要处理一个条目,则此解决方案非常节省内存,因为生成器只产生一个值,然后等待下一个值准备好使用。

于 2012-12-20T17:38:49.620 回答