質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

90.50%

  • Python

    10811questions

    Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

python 条件一致で文字をつなげていく

解決済

回答 4

投稿

  • 評価
  • クリップ 0
  • VIEW 111

22Go

score 12

list hoge 1 2
list hoge2 3 4
list hoge3 5 6
list hoge4 7 8
list hoge5 1 2
list hoge6 3 4
list hoge7 1 2
list hoge8 3 4
list hoge9 5 6
data = []
with open("data", "r") as f:
    for line in f:
        if line.startswith("list"):
            data.append(line.split())
            size = len(data)
            print(size)
            for i in range(size - 1):
                first, next = data[i], data[i+1]
                ("{}-{}".format(first[1], next[1]))
                if int(next[2]) > int(first[3]):
                    data = []
                    print(c[1], n[1])

#理想的な出力結果
#hoge-hoge2-hoge3-hoge4
#hoge5-hoge6
#hoge7-hoge8-hoge9

hogeに与えた2つの数値のうち後者(hoge x y)のyが次の行のhogeのxの数値よりも
大きい場合にhogeをつなげていきたいです。
大きい場合にどんどんつなげていく方法がわからずに困っています。

1行ずつ読み込むよりも一旦ずべてリストに入れてから処理する方がいいのかとも考えております。

できればpandasを使わずに1行ずつの処理で求めてみたいです。

アドバイスお願い致します。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 4

+1

4個目のデータを比較して、前の行より大きかったら2個目のデータchunkリストに格納、
小さかったらchunkリストを結合して dataリストに格納・・・・という処理で実現できるかと思います。

data = []
chunk = []
prev = -1
with open("data", "r") as f:
    for line in f:
        l = line.strip().split()
        if (len(l) != 4) or (l[0] != 'list'):
            continue
        if prev < int(l[3]):
            chunk.append(l[1])
        else:
            data.append('-'.join(chunk))
            chunk = [l[1]]
        prev = int(l[3])
    data.append('-'.join(chunk))

print('\n'.join(data))
#hoge-hoge2-hoge3-hoge4
#hoge5-hoge6
#hoge7-hoge8-hoge9

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

+1

常にhogeの部分を書き出して、条件次第でハイフンか改行文字を付け加えるかを選択していけばいいのではないでしょうか。あんまりPythonらしくない書き方かもしれませんけども。

from os import linesep
from sys import stdout
from io import StringIO
import csv

s = """list hoge 1 2
list hoge2 3 4
list hoge3 5 6
list hoge4 7 8
list hoge5 1 2
list hoge6 3 4
list hoge7 1 2
list hoge8 3 4
list hoge9 5 6"""

# with open(fname, "r") as f: # ファイルから読み込む場合はこちらを使う
with StringIO(s) as f:
    reader = csv.reader(f, delimiter=" ")

    # 一行目は比較対象がないのでforの前に処理しておく。
    (l, hoge, *prev) = next(reader)
    stdout.write(hoge)

    # read remaining rows
    for (l, hoge, *row) in reader:
        if int(row[0]) > int(prev[1]):  # 連結の条件
            stdout.write("-")           # 連結文字
        else:
            stdout.write(linesep)       # 改行文字
        stdout.write(f"{hoge}")
        prev = row[:]
    stdout.write(linesep)               # 必要に応じて
    stdout.flush()                      # 念のためflushしておく

StringIOの部分はデバッグ用です。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2019/03/14 21:44

    stdout.writeしなくてもprint(hoge, end="")で十分では?

    キャンセル

  • 2019/03/14 22:13

    それでもいいですね。直接バッファに書き込むイメージでコードを書いたので、stdoutむき出しにしてました。

    キャンセル

  • 2019/03/16 14:51

    ありがとうございます!

    キャンセル

checkベストアンサー

0

import io

s = """list hoge 1 2
list hoge2 3 4
list hoge3 5 6
list hoge4 7 8
list hoge5 1 2
list hoge6 3 4
list hoge7 1 2
list hoge8 3 4
list hoge9 5 6
"""

before_y = 0
result = [[]]
for line in io.StringIO(s):
    _, hogestr, x, y = line.split()
    x, y = int(x), int(y)
    if x > before_y:
        result[-1].append(hogestr)
    else:
        result[-1] = "-".join(result[-1])
        result.append([hogestr])
    before_y = y
result[-1] = "-".join(result[-1])
print(result)  # => ['hoge-hoge2-hoge3-hoge4', 'hoge5-hoge6', 'hoge7-hoge8-hoge9']

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2019/03/16 14:50

    とてもシンプルでわかりやすいコードでした。
    ありがとうございました。

    キャンセル

0

いったんリストに格納しました。比較のためにzipを使いました。文字列結合結果を作るのにfoldlを使いたかったのですが面倒なのでやめました。

data = []
with open("data", "r") as f:
    rows = list(map(lambda x: (x[1],int(x[2]),int(x[3])),[(l.split()) for l in f if l.startswith("list")]))
data.append(rows[0][0])
for (_,_,e),(h,s,_) in zip(rows[:-1],rows[1:]): # for x,y in zip(rows[:-1],rows[1:]):
    data.append(("-" if e < s else "\n")) # data.append(("-" if x[2] < y[1] else "\n"))
    data.append(h) # data.append(y[0])
else:
    print(''.join(data))


上記のforの変数名を変更しました。x,y --> (_,_,e),(h,s,_)

別解
functools.reduceを使うと短くなりました。pythonらしくないかもしれません。

import functools    
with open("data", "r") as f:
    rows = list(map(lambda x: (x[1],int(x[2]),int(x[3])),[(l.split()) for l in f if l.startswith("list")]))
(h,_,_)=functools.reduce(lambda x,y: (x[0] + ("-" if x[2] < y[1] else "\n") + y[0] ,y[1] ,y[2]), rows)
print(h)

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2019/03/16 14:50

    非常に参考になりました。ありがとうございました。

    キャンセル

同じタグがついた質問を見る

  • Python

    10811questions

    Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。