我有一个很大的元组列表,例如[ (1,2), (1,3), (1,4), (2,1), (2,3) ]
等我想将其转换为[ (1, [1,2,3,4]), (2, [1,3]) ]
有效。我按每个元组的第一个元素对元组进行分组,即(1,2), (1,3), (1,4)
变成(1, [2,3,4])
(同时参见下面的Haskell版本)。我怀疑这可以通过一次完成? 输入列表总是有序的。有效的元组列表
在python
在尝试使用defaultdict
我认为是没有重新发明车轮的自然解决方案。它运作良好,但它不保留键的顺序。一种解决方案是使用有序的defaultdict
作为explained here。
无论如何,我想知道这个问题的语言独立和有效的解决方案。我目前的解决方案需要两个通行证和一个呼叫到set()
列表上。
更新
我想实现以下哈斯克尔版本:
a = [ (1,2), (1,3), (1,4), (2,1), (2,3) ]
b = groupBy (\ x y -> fst x == fst y)
b
[[(1,2),(1,3),(1,4)],[(2,1),(2,3)]]
map (\x -> (fst .head $ x, map snd x)) b
[(1,[2,3,4]),(2,[1,3])]
答案
的性能我实现了两个答案(coldspeed和pm2ring)。在中等大小的清单(高达10^4个元素)中,PM2环解决方案更快;在10^5的大小,都需要相同的时间,在更大的名单COLDSPEED开始赢。下面是数字(用python3)。
第一列是列表中的条目数,第二列是coldspeed
所花的时间,第三列列出的时间为pm2 ring
解决方案。所有时间都在第二。
10 0.0001 0.0000
100 0.0001 0.0000
1000 0.0005 0.0001
10000 0.0044 0.0014
100000 0.0517 0.0452
1000000 0.5579 1.5249
脚本是在这里http://github.com/dilawar/playground/raw/master/Python/so_group_tuple.py
随着阿什维尼优化
PM 2Ring
解决方案甚至更快(约3倍 - 5倍)与阿什维尼的建议。
10 4.887580871582031e-05 1.2636184692382812e-05
100 0.00010132789611816406 2.0742416381835938e-05
1000 0.0005109310150146484 0.000110626220703125
10000 0.004467487335205078 0.0009067058563232422
100000 0.05056118965148926 0.017516136169433594
1000000 0.6100358963012695 0.26450490951538086
10000000 6.092756509780884 2.8253660202026367
随着PYPY
有点混合的结果。最后一列是3
pypy so_group_tuple.py
(10, [1.6927719116210938e-05, 3.409385681152344e-05], 0.4965034965034965)
(100, [4.601478576660156e-05, 8.296966552734375e-05], 0.5545977011494253)
(1000, [0.010258913040161133, 0.0019040107727050781], 5.388054094665665)
(10000, [0.0002448558807373047, 0.00021600723266601562], 1.1335540838852096)
(100000, [0.002658843994140625, 0.0018231868743896484], 1.45834967961292)
(1000000, [0.0833890438079834, 0.02979302406311035], 2.7989452709245284)
(10000000, [1.0556740760803223, 0.6789278984069824], 1.5549133841124023)
我与PM 2Ring
解去,因为它的速度要快得多,直到列表大小10^5列2的比例和列。
请附上您目前的解决方案,并澄清的问题是什么 - 这是不清楚你从第一个列表到第二个列表。 – perigon
[OrderedDict](https://docs.python.org/2/library/collections.html#ordereddict-objects)? – 101
输入列表是否总是这样排序?顺便说一句,你在这个列表中有一个错字。 –