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

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

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

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

Q&A

解決済

3回答

1672閲覧

3行ごとにリストに入れるプログラム

Terratale

総合スコア21

Python

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

0グッド

0クリップ

投稿2018/10/02 12:59

前提・実現したいこと

下の「tekitou」のようなファイルを、一行ずつスペースで区切った形でさらに3行ごとにリストに入れるというプログラムを作りたいと思っています。

tekitou

1あ,い,う,え 2か,き,く,け 3こ,, 4た,ち,,つ 5な,に,ぬ,ね 6は,ひ,ふ,へ 7ま,み,む,

実現したい、リストをprintしたときの出力結果のイメージは以下の通りです。

['あ,い,う,え か,き,く,け こ,,', 'た,ち,,つ な,に,ぬ,ね は,ひ,ふ,へ', 'ま,み,む']

見辛いかもしれませんが、
「え」と「か」の間、「け」と「こ」の間、「つ」と「な」の間、「ね」と「は」の間がスペースで区切られており、また、
「あ」〜「こ,,」、「た」〜「へ」、「ま」〜「む」がそれぞれ別要素として扱われています。

発生している問題・エラーメッセージ

そして、実際に先の内容を実現するため、以下のようなプログラムを作成してみました。

Python3

1# coding: UTF-8 2 3#ライブラリをインポート 4import codecs 5 6#tekitouLogのログをスペース区切り3行ごとを配列に突っ込む方法を模索するプログラム 7 8f_in = codecs.open('tekitou.txt', 'r', 'utf-8')#実験用のログのファイルをutf-8で読み込み 9 10lines = f_in.readlines() #読み込み 11lines2 = [] #空のリストを用意 12 13count = 0 #行数をカウントするための変数 14 15threeline = "" #配列の要素を一時的に入れる変数 16 17for line in lines: 18 count += 1 #行数をカウント 19 text = line.replace("\n","") #\n除去 20 if count%3 != 0: #行数が3の倍数じゃなかった場合 21 threeline += text #1行分をキープ 22 threeline += ' ' #スペースを入れる 23 elif count%3 ==0: #行数が3の倍数だった場合 24 threeline += line #1行分をキープ 25 lines2.append(threeline) #3行溜まったのでリストに追加 26 threeline = "" #変数の中身をリセット 27 28else: 29 f_in.close() 30 31print(lines2) #配列の中身を出力

しかし、これを実行すると、

['あ,い,う,え か,き,く,け こ,,', 'た,ち,,つ な,に,ぬ,ね は,ひ,ふ,へ']

のように、3行に入れず余った「ま,み,む」がリストに入りませんでした。
どのようにプログラムを組めば3行に入らず余ったものも含めた形でリストを作ることができるでしょうか。

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

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

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

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

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

guest

回答3

0

ベストアンサー

現状のコードを最大限利用するなら、ループ後にこんなコードを埋めてやれば良いです。

Python

1if count % 3 != 0: 2 lines2.append(threeline)

書いてみた

面白そうだったので。私ならこう書きます。

Python

1from itertools import zip_longest 2 3 4with open('tekitou.txt') as fin: 5 data = fin.read().split() 6 7 8lines = [ 9 ' '.join( 10 filter(lambda v: v is not None, block) 11 ) 12 for block in zip_longest(*[iter(data)]*3) 13] 14print(*lines, sep='\n')

実行結果 Wandbox

plain

1あ,い,う,え か,き,く,け こ,, 2た,ち,,つ な,に,ぬ,ね は,ひ,ふ,へ 3ま,み,む,

投稿2018/10/02 13:05

編集2018/10/02 13:15
LouiS0616

総合スコア35660

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

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

Terratale

2018/10/02 13:22

回答ありがとうございます。 そっか、たった2行追加するだけで理想通り動いたんですね! itertoolsというライブラリも知りませんでした。知識が増えました、ありがとうございます!
guest

0

リストの最後の要素を一時変数として使ってみました。

python

1txt = """あ,い,う,え 2か,き,く,け 3こ,, 4た,ち,,つ 5な,に,ぬ,ね 6は,ひ,ふ,へ 7ま,み,む, 8""" 9 10result = [] 11for i, line in enumerate(txt.splitlines()): 12 if i % 3 == 0: 13 result.append(line) 14 else: 15 result[-1] += " " + line 16 17print(result) # => ['あ,い,う,え か,き,く,け こ,,', 'た,ち,,つ な,に,ぬ,ね は,ひ,ふ,へ', 'ま,み,む,'] 18

投稿2018/10/02 13:06

hayataka2049

総合スコア30933

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

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

Terratale

2018/10/02 13:19

回答ありがとうございます。 enumerateという関数はじめて知りました。そういった方法もあるんですね!
guest

0

python3

1def chunks(l, n): 2 for i in range(0, len(l), n): 3 yield l[i:i+n] 4 5 6file_path = "data.txt" 7with open(file_path) as f: 8 lines = [line.rstrip("\n") for line in f] 9 10x = [" ".join(line3) for line3 in chunks(lines, 3)] 11print(x)

参考情報

  • Break A List Into N-Sized Chunks

https://chrisalbon.com/python/data_wrangling/break_list_into_chunks_of_equal_size/

  • Pythonのリストを決まったサイズで分割するときはmore-itertoolsのchunkedを使う

http://ariarijp.hatenablog.com/entry/2017/11/02/114539

  • readlines()を使うときに\ nを取り除く

https://code.i-harness.com/ja/q/e8713c

投稿2018/10/02 14:25

katoy

総合スコア22324

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.49%

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

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

質問する

関連した質問