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

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

ただいまの
回答率

88.80%

for文とglob関数併用方法

解決済

回答 1

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 1,349

kak

score 23

いつも勉強させていただいてます。
カレントディレクトリにある”complex.*.pdb” (*に1~1000の数字に振り分けられたファイル)をglob関数で取得していき、pdb=PDBParser().get_structure(”complex.*”, ”complex.*.pdb”)という形に入力していき(*に同じ数字を入力)、(”complex.1”, ”complex.1.pdb”)、(”complex.2”, ”complex.2.pdb”)・・・という形に出力していきたいのですが、for文でくみ合わせると上手くいきませんでした。
同じようなことをしようとしていつもつまづいていますが、ループ処理中に同じ変数を複数個所に含むようなものの処理はどのようにしたらいいのでしょうか。for文を二個組み合わせたりしても2変数がバラバラになり無限ループに陥ります。
お願いします。

In [5]: for filenames in glob.glob("complex.*.pdb"): 
   ...:     for lignames in glob.glob("complex.*.pdb"): 
   ...:        pdb=PDBParser().get_structure(lignames,filenames) 

追記です。
Pythonについての質問です。
教えていただいたコマンドにて以下の様にいくつかのファイルをカレントディレクトリに置いてそれぞれ、id、filenamesを得ることが出来ました。
しかし、PDBParser().get_structure(lignames,filenames)に入力すると何故かcomplex.7.pdbしか処理されませんでした。
PDBParserの仕様によるものだと思うのですが、どなたか原因をご教授ください。

In [8]: for filenames in glob.glob("complex.*.pdb"): 
   ...:        id, ext=os.path.splitext(filenames) 
   ...:        print(id) 
   ...:         
   ...:         
   ...:                                                                             
complex.10
complex.1-2
complex.4
complex.5
complex.8
complex.3
complex.6
complex.2
complex.9
complex.7
In [9]: for filenames in glob.glob("complex.*.pdb"): 
   ...:        id, ext=os.path.splitext(filenames) 
   ...:        print(filenames) 
   ...:         
   ...:         
   ...:         
   ...:                                                                             
complex.10.pdb
complex.1-2.pdb
complex.4.pdb
complex.5.pdb
complex.8.pdb
complex.3.pdb
complex.6.pdb
complex.2.pdb
complex.9.pdb
complex.7.pdb


以下のサイトよりPDBParserのクラス内容です。
https://biopython.org/DIST/docs/api/Bio.PDB.PDBParser%27-pysrc.html#PDBParser.get_structure

  1  # Copyright (C) 2002, Thomas Hamelryck (thamelry@binf.ku.dk) 
  2  # This code is part of the Biopython distribution and governed by its 
  3  # license.  Please see the LICENSE file that should have been included 
  4  # as part of this package. 
  5   
  6  """Parser for PDB files.""" 
  7   
  8  from __future__ import print_function 
  9   
 10  import warnings 
 11   
 12  try: 
 13      import numpy 
 14  except ImportError: 
 15      from Bio import MissingPythonDependencyError 
 16      raise MissingPythonDependencyError( 
 17          "Install NumPy if you want to use the PDB parser.") 
 18   
 19  from Bio.File import as_handle 
 20   
 21  from Bio.PDB.PDBExceptions import PDBConstructionException 
 22  from Bio.PDB.PDBExceptions import PDBConstructionWarning 
 23   
 24  from Bio.PDB.StructureBuilder import StructureBuilder 
 25  from Bio.PDB.parse_pdb_header import _parse_pdb_header_list 
 26   
 27   
 28  # If PDB spec says "COLUMNS 18-20" this means line[17:20] 
 29   
 30   
 31 -class PDBParser(object): 
 32      """Parse a PDB file and return a Structure object.""" 
 33   
 34 +    def __init__(self, PERMISSIVE=True, get_header=False, 
 35                   structure_builder=None, QUIET=False): 
             ...
 65   
 66      # Public methods 
 67   
 68 -    def get_structure(self, id, file): 
 69          """Return the structure. 
 70   
 71          Arguments: 
 72           - id - string, the id that will be used for the structure 
 73           - file - name of the PDB file OR an open filehandle 
 74   
 75          """ 
 76          with warnings.catch_warnings(): 
 77              if self.QUIET: 
 78                  warnings.filterwarnings("ignore", category=PDBConstructionWarning) 
 79   
 80              self.header = None 
 81              self.trailer = None 
 82              # Make a StructureBuilder instance (pass id of structure as parameter) 
 83              self.structure_builder.init_structure(id) 
 84   
 85              with as_handle(file, mode='rU') as handle: 
 86                  self._parse(handle.readlines()) 
 87   
 88              self.structure_builder.set_header(self.header) 
 89              # Return the Structure instance 
 90              structure = self.structure_builder.get_structure() 
 91   
 92          return structure 

PDBParserのせいでは無かったようです。
以下で上手くいきました。

for filenames in glob.glob("complex.*.pdb"):
    id=os.path.splitext(filenames)[0]
    pdb=PDBParser().get_structure(id,filenames)
  • 気になる質問をクリップする

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

質問への追記・修正、ベストアンサー選択の依頼

  • kasa0

    2019/04/10 10:49

    どの言語についての質問なのか明記しましょう。

    キャンセル

  • t_obara

    2019/04/10 13:01

    pythonだとzipが便利だと思います。

    キャンセル

  • kak

    2019/04/10 14:58

    皆様、失礼しました。Pythonについてでした。
    ありがとうございます。zipについて調べてみます。

    キャンセル

回答 1

checkベストアンサー

0

おそらくpythonの質問かと思いますが、どの言語でも共通しているのは、for文を二重にすると組合せのような動きになります。
例えばcomplex.*が2つしか存在しない場合だと、ループ毎の変数は以下の値です。

 処理回数  filenames       lignames      
 1        complex.1.pdb   complex.1.pdb 
 2        complex.1.pdb   complex.2.pdb 
 3        complex.2.pdb   complex.1.pdb 
 4        complex.2.pdb   complex.2.pdb 

今回の場合だとファイル1個に対して1処理なので、for文は1個にしましょう。
そしてfor文のループ変数であるfilenamesをもとに、complex.*の文字列を入れる変数idを作成します。
filenamesidの関係は、filenamesから末尾の拡張子.pdbを削除したものなので、そのようにコードを書きましょう。

id, ext = os.path.splitext(filenames)


するとループ毎の変数は以下のようになるので、それぞれをPDBParser().get_structureに渡せば望み通りの動作になると思います。

 処理回数  filenames       id        
 1        complex.1.pdb   complex.1 
 2        complex.2.pdb   complex.2 
 n        complex.n.pdb   complex.n 
 1000     complex.1000.pdb   complex.1000 

追記
最終的には以下のコードになります。

for filenames in glob.glob("complex.*.pdb"):
    id, ext=os.path.splitext(filenames)
    pdb=PDBParser().get_structure(id,filenames)

投稿

編集

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2019/04/10 15:08

    ご丁寧なご説明ありがとうございます。無事にid、filenamesを取得することが出来ました。しかし、PDBParserに入力しても取得したリストの一番下にあったcomplex.7.pdbの出力しか得られませんでした。自力では原因が分かりません。教えていただけませんでしょうか。

    キャンセル

  • 2019/04/10 18:22

    もしかして`pdb=...`をインデント無しで書いていないでしょうか。これもfor文の中で実行する必要があるため、`id, ext=...`と同じインデントにしてください。(回答に追記しています。)

    キャンセル

  • 2019/04/10 19:21

    インデントは大丈夫だったのですが、'id, ext=...'でidが拡張子入りになってしまったのかもしれません。'id=...[0]'に変更したら上手くいきました。os.path.splitextはとても使い勝手がよさそうでこれからも重宝しそうです。教えていただきありがとうございました!

    キャンセル

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

  • ただいまの回答率 88.80%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

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