2017-01-26 2 views
1

ヘッダーが"Header"文字列で始まるリストがあり、ヘッダーに対応する データがリスト内で連続して続きます。次"Header"接頭辞の要素で終わる: - それは、古典的な種だと延長サブリストのサイズがデータ値に依存する場合のリストの分割(シードと拡張)

data = ["Header: 1", 
     "Some info 1", 
     "Some info 2", 
     "Some info 3", 
     "Header: 2", 
     "Some info 4", 
     "Header: 3", 
     "Some info 5", 
     "Some info 6", 
     ] 
len(data) # returns 9 

私は、ヘッダ・データ要素のリストを作成するには、ヘッダの間隔でリストを分割したいと思います。したがって、最終目標は:

entries = [ ["Header: 1", 
     "Some info 1", 
     "Some info 2", 
     "Some info 3"], 
     ["Header: 2", 
     "Some info 4"], 
     ["Header: 3", 
     "Some info 5", 
     "Some info 6"] 
     ] 
len(data) # returns 3 

各ヘッダーに関連付けられたデータ要素の数は可変です。 各ヘッダーは"Header"で始まるので、これを使用して間隔を とすることができます。 私は解決するために、ループを使用することができます。

entries = [] 
for i in range(0,len(data)): 
    if "Header" in data[i]: 
     entry = [] 
     entry.append(data[i]) 
     i = i + 1 
     while("Header" not in data[i]): 
      entry.append(data[i]) 
      i = i + 1 
      if i == len(data): 
       break 
     entries.append(entry) 

しかし、私は疑問に思うこれを行うことができます1つのライナー(もしくは近いもの)があるのですか? おそらくリストの理解のアプローチ。私はPythonライブラリに精通していませんが、標準ライブラリの解決策もうまくいきます。ここで

entries = [] 
entry = None 
for element in data: 
    if element.startswith('Header'): #or 'Header' in element if it can be everywhere 
     entry = [] 
     entries.append(entry) 
    entry.append(element) 

あなたがこれdataelement Sを反復:

+0

したがって、すべてのヘッダーで始まりますか? –

+0

はい。データのヘッダ要素は常に接頭辞 '' Header ''で始まります。 –

+0

そして、リストがヘッダーで始まっていることは確かに分かりますか?もし何が起こらなければならないのですか? –

答えて

3

あなたは "Headerで始まらない" でitertools.groupby、およびグループを使用することができます。要素の強制リストの反復:今

l = [list(x) for a,x in itertools.groupby(data,lambda x : not x.startswith("Header"))] 

lグループ項目2×2次に[['Header: 1'], ['Some info 1', 'Some info 2', 'Some info 3'], ['Header: 2'], ['Some info 4'], ['Header: 3'], ['Some info 5', 'Some info 6']]

です:

result = [l[i]+l[i+1] for i in range(0,len(l),2)] 

結果:

[['Header: 1', 'Some info 1', 'Some info 2', 'Some info 3'], ['Header: 2', 'Some info 4'], ['Header: 3', 'Some info 5', 'Some info 6']] 

注:動作しません。空の情報ブロックがある場合

+0

Doh!あなたはgroupbyを使って私をパンチに倒した。 – James

+0

非常に良い。これは私が探しているものです! –

3

は、これを行うために、よりエレガントな方法がある私には見えます。 "Header"elementにあるかどうかを確認し、新しい「レコード」を見つけたら、要素がない(初期レコードとして)entryリストを作成し、そのentryentriesに追加します。いずれにしても、entryレコードにelementを追加します。

これが与える実行:

$ python3 
Python 3.5.2 (default, Nov 17 2016, 17:05:23) 
[GCC 5.4.0 20160609] on linux 
Type "help", "copyright", "credits" or "license" for more information. 
>>> data = ["Header: 1", \ 
...   "Some info 1", \ 
...   "Some info 2", \ 
...   "Some info 3",\ 
...   "Header: 2",\ 
...   "Some info 4",\ 
...   "Header: 3", \ 
...   "Some info 5",\ 
...   "Some info 6",\ 
...   ] 
>>> 
>>> entries = [] 
>>> entry = None 
>>> for element in data: 
...  if "Header" in element: 
...   entry = [] 
...   entries.append(entry) 
...  entry.append(element) 
... 
>>> entries 
[['Header: 1', 'Some info 1', 'Some info 2', 'Some info 3'], ['Header: 2', 'Some info 4'], ['Header: 3', 'Some info 5', 'Some info 6']] 

またはPython2中を:

$ python2 
Python 2.7.12 (default, Nov 19 2016, 06:48:10) 
[GCC 5.4.0 20160609] on linux2 
Type "help", "copyright", "credits" or "license" for more information. 
>>> data = ["Header: 1", \ 
...   "Some info 1", \ 
...   "Some info 2", \ 
...   "Some info 3",\ 
...   "Header: 2",\ 
...   "Some info 4",\ 
...   "Header: 3", \ 
...   "Some info 5",\ 
...   "Some info 6",\ 
...   ] 
>>> 
>>> entries = [] 
>>> entry = None 
>>> for element in data: 
...  if "Header" in element: 
...   entry = [] 
...   entries.append(entry) 
...  entry.append(element) 
... 
>>> entries 
[['Header: 1', 'Some info 1', 'Some info 2', 'Some info 3'], ['Header: 2', 'Some info 4'], ['Header: 3', 'Some info 5', 'Some info 6']] 
+0

@izaak_pyzaak:これは通常python2でも動作します。ちょっと待って。 –

+0

@izaak_pyzaak: 'python2'でテストしても、同じ結果が得られます。 –

+0

リストの要素がリストインデックスによってエイリアス化されていることはわかりませんでした。この場合、最初のループでは、 'entries [0]'または 'entry'によって' entries [0] 'にアクセスすることができます –

2

次のコードは、リストをサブリストで展開し、必要に応じてサブリストをマージします。

from itertools import groupby 

splode = [list(g) for k,g in groupby(data, key=lambda x: x.startswith('Header'))] 
merged = [h+i for h,i in zip(splode[::2],splode[1::2])] 

> merged # output is: 
#[['Header: 1', 'Some info 1', 'Some info 2', 'Some info 3'], 
# ['Header: 2', 'Some info 4'], 
# ['Header: 3', 'Some info 5', 'Some info 6']] 
+0

おそらく小さな詳細:OPのテストは '.startswith 'ではない(おそらく' TheHeader'も有効です... –

+0

おそらく、彼の質問の最初の行は "Header " – James

関連する問題