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

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

新規登録して質問してみよう
ただいま回答率
85.48%
Python

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

Q&A

解決済

4回答

377閲覧

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

22Go

総合スコア55

Python

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

0グッド

0クリップ

投稿2019/03/14 10:40

data

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

python

1data = [] 2with open("data", "r") as f: 3 for line in f: 4 if line.startswith("list"): 5 data.append(line.split()) 6 size = len(data) 7 print(size) 8 for i in range(size - 1): 9 first, next = data[i], data[i+1] 10 ("{}-{}".format(first[1], next[1])) 11 if int(next[2]) > int(first[3]): 12 data = [] 13 print(c[1], n[1]) 14 15#理想的な出力結果 16#hoge-hoge2-hoge3-hoge4 17#hoge5-hoge6 18#hoge7-hoge8-hoge9

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

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

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

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

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

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答4

0

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

python

1from os import linesep 2from sys import stdout 3from io import StringIO 4import csv 5 6s = """list hoge 1 2 7list hoge2 3 4 8list hoge3 5 6 9list hoge4 7 8 10list hoge5 1 2 11list hoge6 3 4 12list hoge7 1 2 13list hoge8 3 4 14list hoge9 5 6""" 15 16# with open(fname, "r") as f: # ファイルから読み込む場合はこちらを使う 17with StringIO(s) as f: 18 reader = csv.reader(f, delimiter=" ") 19 20 # 一行目は比較対象がないのでforの前に処理しておく。 21 (l, hoge, *prev) = next(reader) 22 stdout.write(hoge) 23 24 # read remaining rows 25 for (l, hoge, *row) in reader: 26 if int(row[0]) > int(prev[1]): # 連結の条件 27 stdout.write("-") # 連結文字 28 else: 29 stdout.write(linesep) # 改行文字 30 stdout.write(f"{hoge}") 31 prev = row[:] 32 stdout.write(linesep) # 必要に応じて 33 stdout.flush() # 念のためflushしておく

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

投稿2019/03/14 11:57

tachikoma

総合スコア3601

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

hayataka2049

2019/03/14 12:44

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

2019/03/14 13:13

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

2019/03/16 05:51

ありがとうございます!
guest

0

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

Python

1data = [] 2chunk = [] 3prev = -1 4with open("data", "r") as f: 5 for line in f: 6 l = line.strip().split() 7 if (len(l) != 4) or (l[0] != 'list'): 8 continue 9 if prev < int(l[3]): 10 chunk.append(l[1]) 11 else: 12 data.append('-'.join(chunk)) 13 chunk = [l[1]] 14 prev = int(l[3]) 15 data.append('-'.join(chunk)) 16 17print('\n'.join(data)) 18#hoge-hoge2-hoge3-hoge4 19#hoge5-hoge6 20#hoge7-hoge8-hoge9

投稿2019/03/14 11:38

magichan

総合スコア15898

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

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

python

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

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

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

python

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

投稿2019/03/14 12:50

編集2019/03/14 14:53
退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

22Go

2019/03/16 05:50

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

0

ベストアンサー

python

1import io 2 3s = """list hoge 1 2 4list hoge2 3 4 5list hoge3 5 6 6list hoge4 7 8 7list hoge5 1 2 8list hoge6 3 4 9list hoge7 1 2 10list hoge8 3 4 11list hoge9 5 6 12""" 13 14before_y = 0 15result = [[]] 16for line in io.StringIO(s): 17 _, hogestr, x, y = line.split() 18 x, y = int(x), int(y) 19 if x > before_y: 20 result[-1].append(hogestr) 21 else: 22 result[-1] = "-".join(result[-1]) 23 result.append([hogestr]) 24 before_y = y 25result[-1] = "-".join(result[-1]) 26print(result) # => ['hoge-hoge2-hoge3-hoge4', 'hoge5-hoge6', 'hoge7-hoge8-hoge9'] 27

投稿2019/03/14 12:43

hayataka2049

総合スコア30933

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

22Go

2019/03/16 05:50

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問