2011-12-26 36 views
3

我想根據它的每個元素的第一個組件按照lst = {"3", "1", "2", "9"}的順序重新排序Tally[Characters["2723198931"]]的結果。也就是說,我希望輸出爲{{{"3", 2}}, {{"1", 2}}, {{"2", 2}}, {{"9", 2}}}更好的方式來重新排列Mathematica中的列表元素

目前我有一種醜陋的解決方案,但不知道是否有人可以幫助提供一個簡潔的解決方案。非常感謝。

+0

感謝接受。 :-) – 2011-12-26 19:16:39

+0

@ Mr.Wizard:謝謝你永遠的好回答! – 2011-12-26 19:20:53

回答

4

這應該是相當快的,但我沒有測試它。在長列表中,使用Dispatch[rls]可能會獲得更好的性能。

key = {"3", "1", "2", "9"}; 
tal = Tally[Characters["2723198931"]]; 

rls = #[[1]] -> # & /@ tal; 
key /. rls 
{{"3", 2}, {"1", 2}, {"2", 2}, {"9", 2}}

另外,您可以使用這個,這是有點快長理貨清單:

rls = Thread[tal[[All, 1]] -> tal]; 
5

的一種方式可能是

data = Tally[Characters["2723198931"]]; 
lst = {"3", "1", "2", "9"}; 

(*algorithm*) 

pos = Position[data[[All, 1]], #] & /@ lst; 
Extract[data, pos] 

輸出

{{{"3", 2}}, {{"1", 2}}, {{"2", 2}}, {{"9", 2}}} 

更新2:37以上的上午

截屏中,我使用的玻璃V 8.04 7

enter image description here

+0

這就像我所做的一樣,即使我用'Select'代替。有沒有內置函數或更簡單的方法?謝謝! – 2011-12-26 06:56:18

+0

這對我來說不適用於書面。我需要'位置[data [[All,1]],#] [[1]]'。它是否像第8版中寫的那樣工作? – 2011-12-26 07:16:03

+0

@ Mr.Wizard,它的工作原理與V8.04相同,請參閱屏幕截圖! – Nasser 2011-12-26 08:36:55

2

或者,你可以不喜歡

With[{tal = Tally[Characters["2723198931"]]}, 
    [email protected][tal, tal[[All, 1]], #] & /@ key] 

你總是計數字符串中的字符?如果是這樣,直接對字符進行計數可能會更有效,而不是先將其轉換爲字符列表。考慮例如

str = StringJoin[RandomChoice[CharacterRange["0", "9"], 1000]]; 
key = {"3", "1", "2", "9"}; 

({#, StringCount[str, #]} & /@ key) // Timing 

(* output: {0.000121, {{"3", 98}, {"1", 112}, {"2", 99}, {"9", 107}}} *) 

With[{tal = Tally[Characters[str]]}, 
    [email protected][tal, tal[[All, 1]], #] & /@ key] // Timing 

(* output: {0.000567, {{"3", 98}, {"1", 112}, {"2", 99}, {"9", 107}}} *) 
+0

+1並且非常感謝 – 2011-12-26 19:02:15

+0

這些方法的問題在於你掃描了'key'中每個值的列表。如果這個例子在實際使用中具有代表性,那麼這並不重要,但是在較長的「Tally」設置它的效率非常低。在密鑰/計數長度爲5000時,'鍵/。 Dispatch @ Thread [tal [[All,1]] - > tal]'快330倍以上。由於這個時間不長於Pick,並且由於簡單版本更短,速度更快,所以我更願意公佈這種方法。如果單獨提供'StringCount'方法,我會投它,因爲它適合於域。 – 2011-12-26 19:16:17