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

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

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

for文は、様々なプログラミング言語で使われている制御構造です。for文に定義している条件から外れるまで、for文内の命令文を繰り返し実行します。

Python 2.7

Python 2.7は2.xシリーズでは最後のメジャーバージョンです。Python3.1にある機能の多くが含まれています。

Q&A

解決済

3回答

985閲覧

sliceで切り取った文字列の代入

退会済みユーザー

退会済みユーザー

総合スコア0

for

for文は、様々なプログラミング言語で使われている制御構造です。for文に定義している条件から外れるまで、for文内の命令文を繰り返し実行します。

Python 2.7

Python 2.7は2.xシリーズでは最後のメジャーバージョンです。Python3.1にある機能の多くが含まれています。

0グッド

0クリップ

投稿2018/10/24 02:39

編集2018/10/24 02:54
(file1) ATOM 1 N GLY A ATOM 2 CA GLY A ATOM 49 N GLY A ATOM 50 CA GLY A

というファイルがあり、これの2列目を連番にしたいです。
(1 2 49 50 を 1 2 3 4 とする。)
そこで、連番のファイルを作成し、2列目の値と比較して、違っていれば連番の値を代入するというやり方を考えました。

(renban) 1 2 3 4

python

1path = 'file1' 2path2 = 'renban' 3 4f = open(path) 5list = f.readlines() 6f2 = open(path2) 7list2 = f2.readlines() 8 9for (line, line2) in zip(list, list2): 10 line_1 = line[6:8] # 1 2 49 50を抜きだし 11 line2_1 = line2[0:1] # 1 2 3 4を抜きだし 12 a = int(line_1) 13 b = int(line2_1) 14 if a != b: 15 line_1 = line2_1 16 fileobj = open("a.log","a") 17 print >> fileobj, line.rstrip() 18 # ATOM 49 N GLY A -> ATOM 3 N GLY A 19 # ATOM 50 CA GLY A -> ATOM 4 CA GLY A と出力されてほしいが、うまくいっていない。 20  elif a == b: 21 fileobj = open("a.log","a") 22 print >> fileobj, line.rstrip() 23    # ATOM 1 N GLY A 24 # ATOM 2 CA GLY A が出力される。 25 26f.close() 27f2.close()

このようなスクリプトを書いてみたのですが、

python

1if a != b: 2 line_1 = line2_1 3 fileobj = open("a.log","a") 4 print >> fileobj, line.rstrip()

の部分が期待通りになりません。
果たしてこのようなやり方で合っているのか。もっと他にシンプルな書き方があるのか疑問に思っています。

お分かりの方ご教示お願いします。

(現在の結果) ATOM 1 N GLY A ATOM 2 CA GLY A ATOM 49 N GLY A ATOM 50 CA GLY A (得たい結果) ATOM 1 N GLY A ATOM 2 CA GLY A ATOM 3 N GLY A ATOM 4 CA GLY A

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

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

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

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

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

guest

回答3

0

文字列の位置を指定してスライスする方式だと、数字の桁数が3,4,…と増えたときに大変そうなので正規表現を使ってみました。元々の1行のデータ 'ATOM 1 N GLY A' を以下の3つに分割しています。

first = 'ATOM'
second = ' 1'
third = ' N GLY A'

このうち、secondの部分を文字数(len(second))で右寄せした連番に置換してあげれば期待するような結果になると思います。

python

1import re 2 3path = 'file1' 4f = open(path) 5rows = f.readlines() 6f.close() 7 8seq_start = 1 9for i, row in enumerate(rows, seq_start): 10 first, second, third = re.match(r'(\w+)( +\d+)(.*)', row).groups() 11 print(first + str(i).rjust(len(second)) + third) 12 13 # re.sub()を使うことにして、無理矢理1行にすることもできます 14 # print(re.sub(r'( +\d+)', lambda x: str(i).rjust(len(x.group(1))), row.strip('\n')))

投稿2018/10/24 03:50

編集2018/10/24 06:40
退会済みユーザー

退会済みユーザー

総合スコア0

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

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

0

ベストアンサー

2列目を連番にするのであればこれは如何でしょうか?
連番のindexを目的の箇所に差し替えます。

Python

1 2path = 'file1' 3f = open(path).readlines() 4 5index = 1 6out = [] 7for line in f: 8 str_num = str(index).rjust(2) # 右寄せの空白埋めをする 1 -> ' 1' 9 tmp = line[:6] + str_num + line[8:] # 'ATOM ' + ' n' + ' N GLY A \n' 10 out.append(tmp) 11 index += 1 12 13# 出力 14for line in out: 15 fileobj = open("a.log","a") 16 print >> fileobj, line.rstrip()

行数が3桁以上の場合はstr.rjust()の引数を変えて調整できます。
str.rjust()についてはこちらが詳しいです。

投稿2018/10/24 03:39

編集2018/10/24 03:41
suzu6

総合スコア168

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

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

0

恐らく、現在のコードだと「 file1 のn行目の2列目の値が renban のn行目の値と異なっていたら(異なっていなくても) file1 のn行目を a.log に出力する。」というコードになっています。(ただ出力するだけなので、出力される内容がfile1と変わっていない)

質問主さんの意図としては「 file1 のn行目の2列目の値が renban のn行目の値と異なっていたら file1 のn行目をrenbanの値に入れ替えて a.log に出力する。」ことなので入れ替える
処理を実装出来れば解決に近づけると思います。(・ω・)

見当違いでしたら申し訳ありません。。

投稿2018/10/24 03:43

_TM

総合スコア173

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

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

退会済みユーザー

退会済みユーザー

2018/10/24 03:45

おっしゃるとおりです。 その入れ替えるのをどうすればいいかわからず、困っています。 教えていただけないでしょうか?
_TM

2018/10/24 03:56

個人的に、kichirb3さんの解答が綺麗だなと感じました!(丸投げになってしまい申し訳ないですが。。。)
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問