0

これは私が読んでいる生のテキストのサンプルです:

ID: 00000001
SENT: to do something
to    01573831
do    02017283
something    03517283

ID: 00000002
SENT: just an example
just    06482823
an    01298744
example    01724894

今、私はそれをリストのリストのリストに分割しようとしています。

最上位レベルのリスト: ID ごとに、ここに 2 つの要素 (完了)

次のレベル: 各 ID 内で改行で分割

最後のレベル: 各行内で単語と ID を分割します。ID または SENT で始まる行については、それらが分割されているかどうかは問題ではありません。単語と ID の間にはインデント (\t) があります。

現在のコード:

f=open("text.txt","r")
raw=list(f)
text=" ".join(raw)
wordlist=text.split("\n \n ") #split by ID
toplist=wordlist[:2] #just take 2 IDs

編集:単語を別のテキストファイルに相互参照して単語クラスを追加するつもりだったので、リストのリストのリストを要求しました。

手順:

1) .append() を使用して、各単語の単語クラスを追加します

2) "\t".join() を使用して線を接続します

3) "\n".join() を使用して ID 内の異なる行を接続します

4) "\n\n".join() すべての ID を結合して文字列にする

出力:

ID: 00000001
SENT: to do something
to    01573831    prep
do    02017283    verb
something    03517283    noun

ID: 00000002
SENT: just an example
just    06482823    adverb
an    01298744    ind-art
example    01724894    noun
4

4 に答える 4

2

Thorstenの答えのよりpythonicなバージョン:

from collections import namedtuple

class Element(namedtuple("ElementBase", "id sent words")):
    @classmethod
    def parse(cls, source):
        lines = source.split("\n")
        return cls(
            id=lines[0][4:],
            sent=lines[1][6:],
            words=dict(
                line.split("\t") for line in lines[2:]
            )
        )

text = """ID: 00000001
SENT: to do something
to\t01573831
do\t02017283
something\t03517283

ID: 00000002
SENT: just an example
just\t06482823
an\t01298744
example\t01724894"""

elements = [Element.parse(part) for part in text.split("\n\n")]

for el in elements:
    print el
    print el.id
    print el.sent
    print el.words
    print
于 2013-03-25T08:04:49.450 に答える
0

これはあなたのために働くでしょうか?:

トップレベル(あなたが行った)

def get_parent(text, parent):
    """recursively walk through text, looking for 'ID' tag"""

    # find open_ID and close_ID
    open_ID = text.find('ID')
    close_ID = text.find('ID', open_ID + 1)

    # if there is another instance of 'ID', recursively walk again
    if close_ID != -1:
        parent.append(text[open_ID : close_ID])
        return get_parent(text[close_ID:], parent)
    # base-case 
    else:
        parent.append(text[open_ID:])
        return

第 2 レベル: 改行で分割:

def child_split(parent):
    index = 0
    while index < len(parent):
        parent[index] = parent[index].split('\n')
        index += 1

第 3 レベル: 「ID」フィールドと「SENT」フィールドを分割する

def split_field(parent, index):
if index < len(parent):
    child = 0
    while child < len(parent[index]):
        if ':' in parent[index][child]:
            parent[index][child] = parent[index][child].split(':')
        else:
            parent[index][child] = parent[index][child].split()
        child += 1
    return split_field(parent, index + 1)
else:
    return

すべて一緒に実行する:

def main(text):
    parent = []
    get_parent(text, parent)
    child_split(parent)
    split_field(parent, 0)

結果はかなりネストされています。おそらく、多少クリーンアップできますか? それとも、split_fields() 関数が辞書を返すことができるでしょうか?

于 2013-03-25T08:21:00.020 に答える
0

一番上の分割のすべての部分を「オブジェクト」と見なします。したがって、各パーツに対応するプロパティを持つクラスを作成します。

class Element(object):
    def __init__(self, source):
        lines = source.split("\n")
        self._id = lines[0][4:]
        self._sent = lines[1][6:]
        self._words = {}
        for line in lines[2:]:
            word, id_ = line.split("\t")
            self._words[word] = id_

    @property
    def ID(self):
        return self._id

    @property
    def sent(self):
        return self._sent

    @property
    def words(self):
        return self._words

    def __str__(self):
        return "Element %s, containing %i words" % (self._id, len(self._words))

text = """ID: 00000001
SENT: to do something
to\t01573831
do\t02017283
something\t03517283

ID: 00000002
SENT: just an example
just\t06482823
an\t01298744
example\t01724894"""

elements = [Element(part) for part in text.split("\n\n")]

for el in elements:
    print el
    print el.ID
    print el.sent
    print el.words
    print

メインコード (1 行、リスト内包表記) では、テキストは二重の改行ごとにのみ分割されます。次に、すべてのロジックがメソッドに延期され、__init__非常にローカルになります。

クラスを使用すると、 の利点も得られ__str__、オブジェクトの印刷方法を制御できます。

の最後の 3 行を次のように書き換えることも検討できます__init__

self._words = dict([line.split("\t") for line in lines[2:]])

分かりやすいように単純なループを書きました。

クラスを使用すると、

于 2013-03-25T07:53:16.750 に答える
0

必要な出力が正確にはわかりませんが、ニーズに合わせてこれを調整できます (これはitertoolsgrouper レシピを使用します):

>>> from itertools import izip_longest
>>> def grouper(n, iterable, fillvalue=None):
        "Collect data into fixed-length chunks or blocks"
        # grouper(3, 'ABCDEFG', 'x') --> ABC DEF Gxx
        args = [iter(iterable)] * n
        return izip_longest(fillvalue=fillvalue, *args)

>>> with open('text.txt') as f:
        print [[x.rstrip().split(None, 1) for x in g if x.rstrip()]
               for g in grouper(6, f, fillvalue='')]


[[['ID:', '00000001'], ['SENT:', 'to do something'], ['to', '01573831'], ['do', '02017283'], ['something', '03517283']], 
 [['ID:', '00000002'], ['SENT:', 'just an example'], ['just', '06482823'], ['an', '01298744'], ['example', '01724894']]]
于 2013-03-25T08:29:05.360 に答える