2016-03-04 92 views

回答

11
newstring = "".join(s1[i] for i in lst) 

如果你不絕對知道s1不會有太長的任何索引,這樣做:

newstring = "".join(s1[i:i+1] for i in lst) 

它的速度較慢,但​​沒有索引錯誤。

編輯:。已經引起了我的注意,用列表的理解,而不是一臺發電機表達"".join(...)更有效率,所以要做到這一點,只需添加括號:

newstring = "".join([s1[i] for i in lst]) 
+2

如果索引大於字符串的長度,將會引發索引錯誤。在join()中使用生成器表達式也不是非常有效。 – Kasramvd

+0

'lst'是's1'中字符的位置,通過這個定義它不能超出它的範圍 –

+0

@Kasramvd當然,它是由OP使用輸入數據,使其有意義/消毒它。 OP沒有提到他的名單可能沒有意義。這個解決方案很好,可以很容易地調整。 – timgeb

7

另外,使用operator.itemgetter

>>> from operator import itemgetter 
>>> s = '' 
>>> lst = [0, 3, 6, 8] 
>>> ''.join(itemgetter(*lst)(s)) 
'0368' 

既然你問了效率,這應該是比加盟發生器快一點:

In [6]: timeit ''.join(s[i] for i in lst) 
1000000 loops, best of 3: 1.18 µs per loop 

In [7]: timeit ''.join(itemgetter(*lst)(s)) 
1000000 loops, best of 3: 430 ns per loop 

編輯:我也認爲代碼不應該跳過列表,沒有道理。如果列表中存在無意義的索引,您希望代碼提起IndexError,然後從那裏恢復。

+1

您以「或者,...」開頭。或者_to what_? –

+0

@BryanOakley當然的答案。 – timgeb

+0

還應該與'timeit''.join'([i [i] in ist]')進行比較。我做到了,使用'itemgetter'幾乎沒有區別(儘管'itemgetter'仍然稍快。我不想發佈我的號碼,因爲它取決於機器等。 – becko