Dans une liste comme celle ci-dessous:
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']
Il pourrait y avoir des éléments numériques précédés d'un caractère. Je voudrais diviser cela en sous-listes comme ci-dessous:
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']
]
Comme vous pouvez le constater, les listes peuvent ressembler, selon le personnage. Sinon, ils pourraient avoir un nombre différent d’éléments, ou même des éléments dissemblables. Le séparateur principal est le caractère "|"
. J'ai essayé d'exécuter le code suivant pour scinder la liste, mais tout ce que j'obtiens est la même, plus grande, dans une liste. I.e., liste de len(list) == 1
.
import itertools
delim = '|'
smallerlist = [list(y) for x, y in itertools.groupby(biglist, lambda z: z == delim)
if not x]
Des idées comment diviser avec succès?
Tout d’abord, un rapide oneliner , qui n’est pas une solution optimale en termes d’encombrement, mais qui est court et simple:
>>> 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']]
Ici, nous joignons tous les éléments de la grande liste par un séparateur unique n'apparaissant pas, par exemple ,
, puis divisé par |
, puis scindé à nouveau chaque liste en une sous-liste des éléments d'origine.
Mais si vous cherchez un peu plus solution efficace , vous pouvez le faire avec itertools.groupby
qui fonctionnera sur une liste intermédiaire, générée à la volée avec le générateur breakby()
, dans laquelle les éléments sans |
separator sont retournés tels quels, et ceux avec separator sont divisés en 3 éléments: la première partie, un séparateur de liste (par exemple, None
), et la seconde partie.
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]
Il serait plus facile de joindre les éléments de la liste en une seule chaîne, de scinder la chaîne sur le caractère '|'
, puis de diviser chacun de ces éléments sur l'élément que vous avez utilisé pour rejoindre la liste. Probablement une virgule ,
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']]
Si la liste est très longue, vous pouvez également parcourir les éléments de la liste et créer une nouvelle sous-liste lorsque vous rencontrez un caractère de pipe |
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', '']]
Voici une solution à un problème similaire auquel je n’ai pas trouvé de réponse. Comment diviser une liste en sous-listes délimitées par un membre, par ex. personnage:
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']]
Vous n'avez pas besoin de regex ou quoi que ce soit du genre - une simple boucle et str.split()
devrait suffire amplement, du moins si vous recherchez une solution efficace:
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']]