作者uranusjr (←这人是超级笨蛋)
看板Python
标题Re: [问题] 合并两个List
时间Sat Oct 20 18:21:38 2012
※ 引述《Arim (Arim5566)》之铭言:
: 各位版友好
: 如果我想把两个list合并成一个list
: a=[1,2]
: b=[2,5]
: 可以合并成c=[1,2,2,5]
: 作法是
: a.extend(b)
: 但是这个要花O(n)的时间
: 或者是
: a+b
: 用+号这个operator做出来的效果跟extend一模一样
: 但是我不清楚这个operator是不是也是O(n) ?
a + b 会创造出一个新的 list, 里面包含 a 和 b 的所有元素
而用 extend 则是 in-place 的, a.extend(b) 会把 b 的所有元素加入 a 中
这两个 operation 复杂度基本一样
不过我用 timeit 实测好像 + 会快一点点(Python 2.7.2, Mac OS X 10.8.2)
猜测是记忆体 reallocation 的问题吧, 不是什麽有意义的差距就是了
哪个比较好我想也是看状况而定
: 如果也是O(n)的话
: 不知道有没有O(1)的作法?
: 我的想法是
: 直接用a.append(b)
: 这样就变成O(1)
: 不过这样子还要在拆两层以上的list,感觉就麻烦了一点
: 所以想请问有没有比较快的作法(让所有的element都在同一层)
: 谢谢
如果你用 list 的话, O(n) 已经是最快的了
因为需要把 b 里面的每个 reference 都拷贝到 a 里面
当然是 O(n), 没可能是 O(1) 的
如果可以接受用 iterator 的话, 倒是可以用 itertools
a = [1, 2, 3]
b = [4, 5, 6]
from itertools import chain
c = chain.from_iterable([a,b])
for i in c:
print i, # 1 2 3 4 5 6
因为只是产生 iterator, 没有拷贝资料, 基本上是 O(1)
不过这只能用来 walkthrough, 没办法 random access
如果你一定要 random access, 或者可能可以做这种东西
class chain(object):
def __init__(self):
super(object, self).__init__()
self._lists = []
def __getitem__(self, i):
toBreak = False
for l in self._lists:
if toBreak:
break
elif len(l) <= i:
i -= len(l)
else
toBreak = True
return l[i]
def add(self, l):
self._lists.append(list(l))
速度当然是比不上 itertools.chain, 不过比直接运算要快多了
走访和 random access 的速度都是 O(len(_lists))(和各 list 本身的长度无关)
Nested lists 的递回跟其他 list 需要的东西就交给你自己完成了
不知道有没有现成的 module 有类似功能
--
「我最想要的同伴嘛,首先是要笑口常开,其次是我们能永远不会发生误会。
如果这些都能办到的话,嗯,如果他是世界上第一流的桥手,也还不错。」
-- 班尼多‧加罗素,前义大利蓝队成员
--
※ 发信站: 批踢踢实业坊(ptt.cc)
◆ From: 114.32.81.146
※ 编辑: uranusjr 来自: 114.32.81.146 (10/20 18:26)
1F:推 Arim:谢谢!!!! 10/20 18:46
2F:推 deangogi:我在Dive into Python看到是extend比+快 @_@ 10/20 22:31
3F:推 cha122977:学习推 10/21 23:06
4F:→ kdjf:dive into python 是说extend()在所有实作保证O(n) 10/22 13:21
5F:推 retard:长见识推 10/23 08:13