2011-07-12 8 views
1

Iは、例えば、john_fileそれを大型タブ区切りのテキストファイルを呼び出した:Pythonでは、特定の値に基づいてファイルをリストに解析する方法はありますか?

1 john1 23 54 54
2 john2 34 45 66
3 john3 35 43 54
4 john2 34 54 78

5 john1 12 34 65
6 john3 34 55 66

3リーにこのファイルを解析する簡単な方法は何名前(john1、2、3)に基づいていますか?個々のリストはd['john1']に続いている

+0

あなた自身の質問に答えるaldreadyたのですか?あなたの解決策はかなり速いと思われます。 –

+0

@Christian:迅速な対応に感謝します。この例のコードでは、3つのループを記述する必要があります。私の実際のファイルでは、john1からjohn30まで持っていますので、私はより簡潔な方法を探していました。 – user839145

答えて

6
from collections import defaultdict 

d = defaultdict(list) 

with open('john_file.txt') as f: 
    for line in f: 
     fields = line.split('\t') 
     d[fields[1]].append(line) 

事前に

fh=open('john_file.txt','r').readlines() 
john1_list=[] 
for i in fh: 
if i.split('\t')[1] == "john1": 
    john1_list.append(i) 

おかげで、d['john2']など

あなたのような何かを行うことができ
0

:これがないという利点があり

fh=open('john_file.txt','r').readlines() 
john_lists={} 
for i in fh: 
    j=i.split('\t')[1] 
    if j not in johns: 
     john_lists[j]=[] 
    johns[j].append(i) 

を事前に知っている2番目の列。

他の人が指摘するように、あなたも

from collections import defaultdict 
fh=open('john_file.txt','r').readlines() 
john_lists=defaultdict(list) 
for i in fh: 
    j=i.split('\t')[1] 
    johns[j].append(i) 
+0

'john_lists'を' collections.defaultdict(list) 'に設定すると、if文は必要ありません。 –

0
>>> from collections import defaultdict 
>>> a = defaultdict(list) 
>>> for line in '''1 john1 23 54 54 
... 2 john2 34 45 66 
... 3 john3 35 43 54 
... 4 john2 34 54 78 
... 5 john1 12 34 65 
... 6 john3 34 55 66 
... '''.split('\n'): 
... data = filter(None, line.split()) 
... if data: 
... a[data[1]].append(data) 
... 
>>> data 
[] 
>>> a 
defaultdict(<type 'list'>, {'john1': [['1', 'john1', '23', '54', '54'], ['5', 'john1', '12', '34', '65']], 'john2': [['2', 'john2', '34', '45', '66'], ['4', 'john2', '34', '54', '78']], 'john3': [['3', 'john3', '35', '43', '54'], ['6', 'john3', '34', '55', '66']]}) 
0

littletableは、属性によってオブジェクトアクセス/照会可能/旋回可能のリストを作り、この単純なスライスの種類と簡単にダイシングを行い行うためにdefaultdictを使用することができます、メモリ内のミニ・データベースと同様ですが、SQLiteよりもオーバーヘッドが少なくて済みます。

from collections import namedtuple 
from littletable import Table 

data = """\ 
1 john1 23 54 54 
2 john2 34 45 66 
3 john3 35 43 54 
4 john2 34 54 78 
5 john1 12 34 65 
6 john3 34 55 66""" 

Record = namedtuple("Record", "id name length width height") 
def makeRecord(s): 
    s = s.strip().split() 
    # convert all but name to ints, and build a Record instance 
    return Record(*(ss if i == 1 else int(ss) for i,ss in enumerate(s))) 

# create a table and load it up 
# (if this were CSV data, would be even simpler) 
t = Table("data") 
t.create_index("id", unique=True) 
t.create_index("name") 
t.insert_many(map(makeRecord, data.splitlines())) 

# get a record by unique key 
# (unique indexes return just the single record) 
print t.id[4] 
print 

# get all records matching an indexed value 
# (non-unique index retrievals return a new Table) 
for d in t.name['john1']: 
    print d 
print 

# dump summary pivot tables 
t.pivot('name').dump_counts() 
print 

t.create_index('length') 
t.pivot('name length').dump_counts() 

プリント:

Record(id=4, name='john2', length=34, width=54, height=78) 

Record(id=1, name='john1', length=23, width=54, height=54) 
Record(id=5, name='john1', length=12, width=34, height=65) 

Pivot: name 
john1  2 
john2  2 
john3  2 

Pivot: name,length 
      12  23  34  35 Total 
john1  1  1  0  0  2 
john2  0  0  2  0  2 
john3  0  0  1  1  2 
Total  1  1  3  1  6 
関連する問題