2017-06-21 10 views
1

map、reduce、filterを使用してこのコードをもっとpythonicな方法で記述したいと思います。誰かがそれで私を助けることができますか?Python 3を使用して文字列を反復する

これは文字列内の位置に基づいて文字列に合計値を割り当てる単純なコードです。例えば、文字列abaacab

a b a a c a b 
1 2 3 4 occurrence of a 
    1   2 occurrence of b 
     1  occurrence of c 
1+1+2+3+1+4+2 = 14 

import sys 
check, total = {}, 0 
for i, v in enumerate(sys.argv[1]): 
    if v in check: 
     check[v] += 1 
    else: 
     check[v] = 1 
    total += check[v] 
print(total) 
+1

なぜdownvoteですか? –

+1

私は投票しませんでしたが、人々があなたの側から研究努力やプログラミングの試みを期待していると思います。今では基本的に人々にコードを書くように求めています。 – quinz

+0

どうしますか? –

答えて

1
import sys 
val = {v : sys.argv[1].count(v) for v in set(sys.argv[1])} 
total = sum(val[k] * (val[k] + 1) // 2 for k in val) 

3行...バニラパイソンの1本のインポートおよび2線用 。

最初の行は、カウントの文字のマッピングを作成します。次に、2行目はリスト内包表記内の各文字のシーケンスの合計を求め、2番目の文字は各文字の合計を合計します。sum

出力:

val: {'a': 4, 'c': 1, 'b': 2} 
total: 14 

警告:これは、各文字(線形複雑度)のための数を計算するので、効率的ではありません。

4

あなたが現在行っている方法で結果を計算したいのであれば、あなたの現在のコードはできるだけPythonに近いと思います(唯一の例外は不要なenumerate呼び出しです)。

しかし、私はあなたがそれらを作るようにカウントを加算するよりもtotalを見つけるより良い方法があると思います。各値によって提供された合計の部分は、その値の最終カウント(三角の数)から直接計算することができます。つまり、一度に値を数え、最後に合計を計算することができます。ここで

が、私はそれを行うだろう方法は次のとおりです。私はあなたのコードを作ることができると言うでしょう

import sys 
import collections 

counts = collections.Counter(sys.argv[1]) 
total = sum(n * (n+1) // 2 for n in counts.values()) 
print(total) 
+0

'n *(n + 1)// 2'の代わりに、より遅くて分かりやすいものが' sum(range(n + 1)) 'になります。 –

+0

私の答えです。 :p –

+0

@Rawingそれは本当に遅く、最適化されていませんか? (私は現在、自分でそれを実行することはできません) – bbastu

0

唯一の方法は、よりPython的にはされている実際のカウントを合理化する代わりに、通常のdictCounterオブジェクトを、使用していますdictによって行わ:

>>> from collections import Counter 
>>> counts = Counter() 
>>> s = "abaacab" 
>>> total = 0 
>>> for c in s: 
...  counts[c] += 1 
...  total += counts[c] 
... 
>>> total 
14 
1

SO喜んで、ここでは実際には、あなたがそれをしたいとあなたが望むないことを別の答えです。 Python3に準拠し、Python2でテストしていません。

from functools import reduce, partial 
total = reduce(lambda x, y: x + y, map(lambda x: x * (x + 1) // 2, map(partial(str.count, sys.argv[1]), set(sys.argv[1])))) 
print(total) 

出力

14 

それを破壊:

partial(str.count, sys.argv[1]) ---- (1)mapsys.argvに適用されます高階関数を定義します。この方法で、あなたのカウントが作成されます。 dictは最終回答には必要ないので作成されません。

map(---(1)---, set(sys.argv[1])) ---- (2)(1)

map(lambda x: x * (x + 1) // 2, ----(2)----) ----(3)(2)によって生成されたカウントを取得し、その後、和を得るためにAPを適用する部分関数を適用します。

reduce(lambda x, y: x + y, ----(3)----)は、(3)からの合計で合計します。

関連する問題