以下のようなリストで:
_biglist = ['X', '1498393178', '1|Y', '15496686585007',
'-82', '-80', '-80', '3', '3', '2', '|Y', '145292534176372',
'-87', '-85', '-85', '3', '3', '2', '|Y', '11098646289856',
'-91', '-88', '-89', '3', '3', '2', '|Y', '35521515162112',
'-82', '-74', '-79', '3', '3', '2', '|Z',
'0.0', '0.0', '0', '0', '0', '0', '0', '4', '0', '154']
_
文字の前にいくつかの数値要素がある場合があります。これを以下のようなサブリストに分割したいと思います。
_smallerlist = [
['X', '1498393', '1'],
['Y', '1549668', '-82', '-80', '-80', '3', '3', '2', ''],
['Y', '1452925', '-87', '-85', '-85', '3', '3', '2', ''],
['Y', '3552151', '-82', '-74', '-79', '3', '3', '2', ''],
['Z', '0.0', '0.0', '0', '0', '0', '0', '0', '4', '0', '154']
]
_
ご存知のように、キャラクターによっては、リストが似ている可能性があります。それ以外の場合は、要素の数が異なる場合や、要素がまったく異なる場合があります。主な区切り文字は_"|"
_文字です。次のコードを実行してリストを分割しようとしましたが、取得できるのはリスト内の同じ、より大きなリストです。つまり、len(list) == 1
のリストです。
_import itertools
delim = '|'
smallerlist = [list(y) for x, y in itertools.groupby(biglist, lambda z: z == delim)
if not x]
_
うまく分割する方法はありますか?
まず、簡単なonelinerです。これは、スペース要件に関して最適なソリューションではありませんが、短くて便利です。
_>>> smallerlist = [l.split(',') for l in ','.join(biglist).split('|')]
>>> smallerlist
[['X', '1498393178', '1'],
['Y', '15496686585007', '-82', '-80', '-80', '3', '3', '2', ''],
['Y', '145292534176372', '-87', '-85', '-85', '3', '3', '2', ''],
['Y', '11098646289856', '-91', '-88', '-89', '3', '3', '2', ''],
['Y', '35521515162112', '-82', '-74', '-79', '3', '3', '2', ''],
['Z', '0.0', '0.0', '0', '0', '0', '0', '0', '4', '0', '154']]
_
ここでは、大きなリストのすべての要素を、表示されない一意のセパレーター(たとえば、_,
_)で結合し、次に_|
_で分割し、各リストを元の要素のサブリストに再度分割します。
しかし、もう少し効率的なソリューションを探している場合は、 _itertools.groupby
_ を使用してそれを実行できます。 breakby()
ジェネレーターを使用してオンザフライで生成される中間リストを操作します。この場合、_|
_セパレーターのない要素はそのまま返され、セパレーターのある要素は3つの要素に分割されます:最初の部分、リスト-delimiter(例None
)、および2番目の部分。
_from itertools import groupby
def breakby(biglist, sep, delim=None):
for item in biglist:
p = item.split(sep)
yield p[0]
if len(p) > 1:
yield delim
yield p[1]
smallerlist = [list(g) for k,g in groupby(breakby(biglist, '|', None),
lambda x: x is not None) if k]
_
リストの要素を単一の文字列に結合し、'|'
文字で文字列を分割し、リストの結合に使用したもので各要素を分割する方が簡単です。おそらくカンマ,
bigstr = ','.join(biglist)
[line.split(',') for line in bigstr.split('|')]
# returns
[['X', '1498393178', '1'],
['Y', '15496686585007', '-82', '-80', '-80', '3', '3', '2', ''],
['Y', '145292534176372', '-87', '-85', '-85', '3', '3', '2', ''],
['Y', '11098646289856', '-91', '-88', '-89', '3', '3', '2', ''],
['Y', '35521515162112', '-82', '-74', '-79', '3', '3', '2', ''],
['Z', '0.0', '0.0', '0', '0', '0', '0', '0', '4', '0', '154']]
リストが非常に長い場合は、リスト内の項目を反復処理して、パイプ文字|
が検出されたときに新しいサブリストを作成することもできます。
new_biglist = []
sub_list = []
for item in biglist:
if '|' in item:
end, start = item.split('|')
sub_list.append(end)
new_biglist.append(sub_list)
sub_list = [start]
else:
sub_list.append(item)
new_biglist
# return:
[['X', '1498393178', '1'],
['Y', '15496686585007', '-82', '-80', '-80', '3', '3', '2', ''],
['Y', '145292534176372', '-87', '-85', '-85', '3', '3', '2', ''],
['Y', '11098646289856', '-91', '-88', '-89', '3', '3', '2', ''],
['Y', '35521515162112', '-82', '-74', '-79', '3', '3', '2', '']]
これは私が答えを見つけられなかった同様の問題の解決策です。リストをメンバーで区切られたサブリストに分割する方法。キャラクター:
l = ['r', 'g', 'b', ':',
'D', 'E', 'A', 'D', '/',
'B', 'E', 'E', 'F', '/',
'C', 'A', 'F', 'E']
def split_list(thelist, delimiters):
''' Split a list into sub lists, depending on a delimiter.
delimiters - item or Tuple of item
'''
results = []
sublist = []
for item in thelist:
if item in delimiters:
results.append(sublist) # old one
sublist = [] # new one
else:
sublist.append(item)
if sublist: # last bit
results.append(sublist)
return results
print(
split_list(l, (':', '/'))
)
# => [['r', 'g', 'b'], ['D', 'E', 'A', 'D'],
# ['B', 'E', 'E', 'F'],
# ['C', 'A', 'F', 'E']]
正規表現やその他の種類は必要ありません-少なくとも実際の効率的なソリューションが必要な場合は、単純なループとstr.split()
で十分です。
biglist = ['X', '1498393178', '1|Y', '15496686585007', '-82', '-80', '-80', '3', '3', '2',
'|Y', '145292534176372', '-87', '-85', '-85', '3', '3', '2', '|Y',
'11098646289856', '-91', '-88', '-89', '3', '3', '2', '|Y', '35521515162112',
'-82', '-74', '-79', '3', '3', '2', '|Z', '0.0', '0.0', '0', '0', '0', '0',
'0', '4', '0', '154']
delimiter = "|"
smaller_list = [[]]
for x in biglist:
if delimiter in x:
a, b = x.split(delimiter)
if a: # remove the check if you also want the empty elements
smaller_list[-1].append(a)
smaller_list.append([])
if b: # remove the check if you also want the empty elements
smaller_list[-1].append(b)
else:
smaller_list[-1].append(x)
print(smaller_list)
# [['X', '1498393178', '1'],
# ['Y', '15496686585007', '-82', '-80', '-80', '3', '3', '2'],
# ['Y', '145292534176372', '-87', '-85', '-85', '3', '3', '2'],
# ['Y', '11098646289856', '-91', '-88', '-89', '3', '3', '2'],
# ['Y', '35521515162112', '-82', '-74', '-79', '3', '3', '2'],
# ['Z', '0.0', '0.0', '0', '0', '0', '0', '0', '4', '0', '154']]