7

文字が任意の順序である可能性のあるテキストから、文字の種類と数を引き出すことができるようにしたいと考えています。私が取り組んでいる他の解析が行われていますが、このビットには困惑しています!

input -> result
"abc" -> [['a',1], ['b',1],['c',1]]
"bbbc" -> [['b',3],['c',1]]
"cccaa" -> [['a',2],['c',3]]

検索またはスキャンを使用して、可能な文字ごとに繰り返すことができますが、それを行うクリーンな方法はありますか?

これは私が得た限りです:

from pyparsing import *


def handleStuff(string, location, tokens):

        return [tokens[0][0], len(tokens[0])]


stype = Word("abc").setParseAction(handleStuff)
section =  ZeroOrMore(stype("stype"))


print section.parseString("abc").dump()
print section.parseString("aabcc").dump()
print section.parseString("bbaaa").dump()
4

5 に答える 5

6

1 つの解決策:

text = 'sufja srfjhvlasfjkhv lasjfvhslfjkv hlskjfvh slfkjvhslk'
print([(x,text.count(x)) for x in set(text)])

パイパーシングは含まれていませんが、やり過ぎのようです。

于 2010-01-25T18:38:58.470 に答える
6

すべてのテストケースで、文字は常にグループ化されていたため、入力文字を「ababc」のように混在させることができるかどうかは、あなたの説明からはわかりませんでした。文字常にグループ化されている場合は、次の pyparsing コードを使用できます。

def makeExpr(ch):
    expr = Word(ch).setParseAction(lambda tokens: [ch,len(tokens[0])])
    return expr

expr = Each([Optional(makeExpr(ch)) for ch in "abc"])

for t in tests:
    print t,expr.parseString(t).asList()

Each コンストラクトは順不同のマッチングを処理し、Word(ch) は 1 対 n の繰り返しを処理します。parse アクションは、解析されたトークンを (character, count) タプルに変換します。

于 2010-01-26T03:15:28.400 に答える
3

Lennart の 1 行のソリューションが気に入っています。

Alex は、3.1 を使用している場合の別の優れたオプションについて言及しています。

さらに別のオプションはcollections.defaultdictです:

>>> from collections import defaultdict
>>> mydict = defaultdict(int)
>>> for c in 'bbbc':
...   mydict[c] += 1
...
>>> mydict
defaultdict(<type 'int'>, {'c': 1, 'b': 3})
于 2010-01-25T19:00:55.317 に答える
2

純粋な pyparsing アプローチが必要な場合、これはほぼ正しいと感じます。

from pyparsing import *

# lambda to define expressions
def makeExpr(ch):
    expr = Literal(ch).setResultsName(ch, listAllMatches=True)
    return expr

expr = OneOrMore(MatchFirst(makeExpr(c) for c in "abc"))
expr.setParseAction(lambda tokens: [[a,len(b)] for a,b in tokens.items()])


tests = """\
abc
bbbc
cccaa
""".splitlines()

for t in tests:
    print t,expr.parseString(t).asList()

版画:

abc [['a', 1], ['c', 1], ['b', 1]]
bbbc [['c', 1], ['b', 3]]
cccaa [['a', 2], ['c', 3]]

しかし、これは pyparsing の難解な機能のいくつかに依存しているため、あいまいなコード領域に入り始めています。一般的に、defaultdict を使用する頻度カウンターが好きです (Counter はまだ試していません)。これは、何をしているかが明確であるためです。

于 2010-01-26T03:08:28.730 に答える
1

pyparsing away -- Python 3.1 では、collections.Counterにより、このようなカウント作業が非常に簡単になります。CounterPython 2 用の適切なバージョンは、ここにあります。

于 2010-01-25T18:51:15.997 に答える