2016-08-22 9 views
0

内のファイルからdictsを作成する、私は何とか<の内側にあるものを読む必要があり、私はキーは、例えばパイソン

dict = { "something":[1,5,8], "somethingelse": "hello" ...} 

で辞書を作成する必要があり

<<something>> 1, 5, 8 
<<somethingelse>> hello 
<<somethingelseelse>> 1,5,6 

のようなマルチラインを使用してファイルを持っています< >>をキーとして入れて、たくさんの要素があるかどうかを調べる必要があります.1つしかなければ文字列として入れます。それ以上の場合は、要素のリストとして配置する必要があります。 私を助けるためにどのようなアイデアですか? おそらくregExのものですが、私はそれほど素晴らしいものではありません。

私は簡単にファイルの行を読んでいるDEFを作成しますが、これらの値を分離する方法がわからない:

f = open('something.txt', 'r') 
lines = f.readlines() 
f.close() 

def finding_path(): 
    for line in lines: 
     print line 

finding_path() 
f.close() 

任意のアイデア?ありがとう:)

+0

ので、複数の値があるのでしょうか?コンマがある場合は?あなたは常に*整数*を持っていますか(期待される出力は数字をint値に変換しています)。 –

+0

ルールはありませんが、 "、"記号があるかどうかを確認することができますので、1つ以上の値があることを確認してください。 "、"がない場合は単なる文字列になりますが、それらは常に整数ではなく、可能な文字列でも構いませんが、単一の文字列ではなくリストに入れる必要があります – degath

+0

ファイルを閉じる必要はありません二度。そして、なぜグローバルに使うのではなく、ファイル名を関数に渡すのはなぜですか? –

答えて

1

あなたのキーは常に単一の単語であると仮定すると、あなたはsplit(char, maxSplits)で遊ぶことができます。

<<one>> 1, 5, 8 
<<two>> hello 
// this is a comment, it will be skipped 
<<three>> 1,5,6 

以下のようなファイルを使用して

import sys 

def finding_path(file_name): 
    f = open(file_name, 'r') 
    my_dict = {} 
    for line in f: 
     # split on first occurance of space 
     key_val_pair = line.split(' ', 1) 
     # if we do have a key seprated by a space 
     if len(key_val_pair) > 1: 
      key = key_val_pair[0] 
      # proceed only if the key is enclosed within '<<' and '>>' 
      if key.startswith('<<') and key.endswith('>>'): 
       key = key[2:-2] 
       # put more than one value in list, otherwise directly a string literal 
       val = key_val_pair[1].split(',') if ',' in key_val_pair[1] else key_val_pair[1] 

       my_dict[key] = val 
    print my_dict 
    f.close() 

if __name__ == '__main__': 
    finding_path(sys.argv[1]) 

以下のようなもの、私は出力

{'three': ['1', '5', '6\n'], 'two': 'hello\n', 'one': ['1', ' 5', ' 8\n']} 
+0

必要な出力は{'three':[1,5,6]、 'two': 'hello \ n'、 'one':[1,5,8]}です。 –

+0

@DineshPundkar:あなたの答えはそれを達成できませんどちらか。 –

+0

'fを呼び出す必要はありません。readlines() ';ファイルオブジェクトを直接反復処理することができます。空の辞書を作成する方が '{}'で行う方が良い(組み込み関数を参照して呼び出すよりもむしろオペコードを使う方が速い)。おそらく、グローバルを使用するのではなく、ファイル名を関数に渡したいと思うでしょう。なぜ 'f.close()' *を2回呼び出すのですか?ファイルオブジェクトを 'with'文でコンテキストマネージャとして使用し、ファイルが自動的に閉じられるようにすることができます(例外があったとしても)。 –

1

を取得する以下のコードを確認してください:取得するために正規表現を使用し

  • をキーと値

  • 値リストの長さが1の場合、文字列に変換します。

import re 
demo_dict = {} 

with open("val.txt",'r') as f: 
    for line in f: 
      m= re.search(r"<<(.*?)>>(.*)",line) 
      if m is not None: 
       k = m.group(1) 
       v = m.group(2).strip().split(',') 
       if len(v) == 1: 
        v = v[0] 
       demo_dict[k]=v 
print demo_dict 

出力:

C:\Users\dinesh_pundkar\Desktop>python demo.Py 
{'somethingelseelse': [' 1', '5', '6'], 'somethingelse': 'hello', 'something': [ 
' 1', ' 5', ' 8']} 
+0

AttributeError: 'NoneType'オブジェクトに 'group'属性がありません – degath

+0

@degath:正規表現と一致しない行があります。例えば、その行は空であってもよい。 'm is None'が真である行をスキップします。 –

+0

今、残っているのは、正規表現が一致しなかった行をスキップすることだけです。 –

1

私の答えはディネッシュさんに似ています。可能な場合はリストの値を数値に変換する関数を追加し、行が一致しない場合に有用な警告が表示されるようにエラー処理を追加しました。

import re 
import warnings 

regexp =re.compile(r'<<(\w+)>>\s+(.*)') 

lines = ["<<something>> 1, 5, 8\n", 
     "<<somethingelse>> hello\n", 
     "<<somethingelseelse>> 1,5,6\n"] 

#In real use use a file descriptor instead of the list 
#lines = open('something.txt','r') 

def get_value(obj): 
    """Converts an object to a number if possible, 
    or a string if not possible""" 
    try: 
     return int(obj) 
    except ValueError: 
     pass 
    try: 
     return float(obj) 
    except ValueError: 
     return str(obj) 

dictionary = {} 

for line in lines:  
    line = line.strip() 
    m = re.search(regexp, line) 
    if m is None: 
     warnings.warn("Match failed on \n {}".format(line)) 
     continue 
    key = m.group(1) 
    value = [get_value(x) for x in m.group(2).split(',')] 
    if len(value) == 1: 
     value = value[0] 
    dictionary[key] = value 

print(dictionary) 

出力ルールを何によって

{'something': [1, 5, 8], 'somethingelse': 'hello', 'somethingelseelse': [1, 5, 6]}