-2

列が 1 つしかないテキスト ファイルがあります。必要なのは、唯一の列をいくつかの列に分割することです。たとえば、私のファイルが次のもので構成されているとします。

10

20

30

40

50

e

1467年

1608年

1733年

1767年

1878年

e

1787年

1353

1024

693

423

以下のようになる必要があります。

10 1467 1787

20 1608 1353

30 1733 1024

40 1767 693

50 1878 423

Pythonスクリプトでそれを行うのを手伝ってくれるかどうか疑問に思っていました. また、OS X端末でコマンドを書いてできることがあれば教えてください。

4

3 に答える 3

1

リスト内包表記と itertools モジュールでできることの例を次に示します。

>>> from itertools import dropwhile, izip, takewhile
>>> l = ['1', '2', 'X', '3', '4', 'X', '5', '6']
>>> splitter = 'X'
>>> fun = lambda e: e != 'X'
>>> begin = [e for e in takewhile(fun, l)]
>>> end = [e for e in dropwhile(fun, l)][1:]
>>> begin, end
(['1', '2'], ['3', '4', 'X', '5', '6'])
>>> # OUT: (['1', '2'], ['3', '4', 'X', '5', '6'])
>>> mid = [e for e in takewhile(fun, end)]
>>> end = [e for e in dropwhile(fun, end)][1:]
>>> begin, mid, end
(['1', '2'], ['3', '4'], ['5', '6'])
>>> # OUT: (['1', '2'], ['3', '4'], ['5', '6'])
>>> [e for e in izip(begin, mid, end)]
[('1', '3', '5'), ('2', '4', '6')]
>>> # OUT: [('1', '3', '5'), ('2', '4', '6')]

もちろん、元のリストが可変長の場合は、この作業をループで行う必要があります。

インタラクティブな例を簡単にテストできるように、この種のステートメントをBPython インタープリターでテストすることをお勧めします。

于 2012-08-07T09:26:36.523 に答える
0

以下を使用して、ファイル全体の内容をリストに分割できます。

def read_data(filename):
    with open(filename) as f:
        return f.read().split()

data = read_data('test.txt')以下を含むを使用して実行text.txt:

10
20
30
e
11
21
31
e
12
22
32

結果は次のとおりです。

data = ['10', '20', '30', 'e', '11', '21', '31', 'e', '12', '22', '32']

注:正しく処理test.txtされるように、スペース、タブ、および改行を使用してフォーマットできます。split()

データは、'e' エントリを含まない 2D 配列にある必要があります。これは、次を使用して実行できます。

def list_to_grid(data):
    ret  = []
    line = []
    for entry in data:
        if entry == 'e':
            if len(line) != 0:
                ret.append(line)
                line = []
            else:
                line.append(int(entry))
    if len(line) != 0:
        ret.append(line)
    return ret

注: これを行うにはもっと Pythonic な方法があると思いますが、うまくいきます。

ファイルで実行data = list_to_grid(read_data('test.txt'))すると、次のようになります。text.txt

data = [[10, 20, 30], [11, 21, 31], [12, 22, 32]]

あなたがしているのは、2D配列の転置です。つまり、与えられたdata[i][j]、それは新しい位置 を持っていdata[j][i]ます。これで、このデータを転置して目的のシーケンスを取得できます。

def transpose(data):
    ret = []
    for i in range(0, len(data)):
        ret.append([data[j][i] for j in range(0, len(data[i]))])
    return ret

どちらがtdata = transpose(data)与えます:

 data = [[10, 20, 30], [11, 21, 31], [12, 22, 32]]
tdata = [[10, 11, 12], [20, 21, 22], [30, 31, 32]]

今すぐ印刷してください:

def print_data(data):
    for line in data:
        print ' '.join([str(x) for x in line])

使用print_data(tdata)すると、次の結果が得られます。

10 11 12
20 21 22
30 31 32

それはあなたが望んでいたものです。

于 2012-08-07T10:07:29.577 に答える
0

注:変更されたデータ形式を反映するために修正されました

グループ区切り文字として 'e' を使用した (新しい) サンプル データに基づいています。基本的な考え方は、ファイルのグループ化の行を繰り返し処理し、区切り文字が表示されるたびに新しいグループを開始することです。

# testdata contains:
10
20
30
40
50
e
1467
1608
1733
1767
1878
e
1787
1353
1024
693
423

_

DELIMITER = 'e'
groups = []
this_group = []
for l in open('testdata', 'r'):
    l = l.strip()
    if l == DELIMITER and this_group:
        groups.append(this_group)
        this_group = []
    else:
        this_group.append(l)
if this_group:
    groups.append(this_group)

for t in zip(*groups):
    print ' '.join(t)

10 1467 1787
20 1608 1353
30 1733 1024
40 1767 693
50 1878 423
于 2012-08-07T09:26:48.397 に答える