2009-03-27 2 views
0

Я боролся с управлением некоторыми данными. У меня есть данные, которые я превращались в список списков каждый базовый подсписок имеет структуру, подобную следующейЧтение и группировка списка данных в Python

<1x>begins 
<2x>value-1 
<3x>value-2 
<4x>value-3 
some indeterminate number of other values 
<1y>next observation begins 
<2y>value-1 
<3y>value-2 
<4y>value-3 
some indeterminate number of other values 

это продолжается в течение неопределенного количества времени в каждом подсписка

EDIT Мне нужно, чтобы получить все вхождений < 2, < 4 отделялись и сгруппированы вместе я создаю новый список списков [[< 2x> значение-1, < 3x> ценностно-2, < 4x> ценностно-3], [< 2y > значение-1, < 3y> значение-2, < 4y> значение-3]]

EDIT все строки, которые следуют < 4x> и < 4y> (и в этом отношении < 4anyalpha> имеют одинаковый тип кодирования, и я не знаю априори, насколько высоки числа, эти как теги sgml, которые не закрыты, я использовал числа, потому что мои пальцы болели от всего кодирования, которое я делал сегодня.

Решение, которое я придумал, наконец, не очень красиво

listINeed=[] 
for sublist in biglist: 
    for line in sublist: 
     if '<2' in line: 
      var2=line 
     if '<3' in line: 
      var3=line 
     if '<4' in line: 
      var4=line 
      templist=[] 
      templist.append(var2) 
      templist.append(var3) 
      templist.append(var4) 
      listIneed.append(templist) 
      templist=[] 
      var4=var2=var3='' 

Я смотрел на способы, чтобы попытаться очистить это, но не увенчались успехом. Это прекрасно работает, я просто видел это как еще одну возможность узнать больше о python, потому что я думаю, что это должно обрабатываться одной строкой.

+0

Это помогло бы, если бы вы могли отредактировать свой вопрос, чтобы дать лучшее описание того, что вы хотите - это действительно не ясно, как вы его сейчас. –

+0

Если это список списков, почему вы показываете это в обозначении «<1x> бла»? Почему бы не показать это как реальные списки списков? [[1, x, blah], [2, x, value-1], ...] Что у вас ДЕЙСТВИТЕЛЬНО? Список строк? Почему так? –

+0

Потому что так поступает исходный файл.Я прочитал в исходном файле, и в начале каждой строки есть теги, которые я должен использовать, чтобы определить, что обрабатывать. Каждый исходный файл является подсписком. Нотация состоит в том, что каждая строка начинается с тэга SGML – PyNEwbie

ответ

1

Вы в хорошем начале, заметив, что ваше оригинальное решение может работать, но не имеет элегантности.

Вы должны разобрать строку в цикле, создав новую переменную для каждой строки. Вот некоторые примеры кода:

import re 

s = """<1x>begins 
<2x>value-1 
<3x>value-2 
<4x>value-3 
some indeterminate number of other values 
<1y>next observation begins 
<2y>value-1 
<3y>value-2 
<4y>value-3""" 
firstMatch = re.compile('^\<1x') 
numMatch = re.compile('^\<(\d+)') 
listIneed = [] 
templist = None 
for line in s.split(): 
     if firstMatch.match(line): 
       if templist is not None: 
         listIneed.append(templist) 
       templist = [line] 
     elif numMatch.match(line): 
      #print 'The matching number is %s' % numMatch.match(line).groups(1) 
      templist.append(line) 
if templist is not None: listIneed.append(templist) 

print listIneed 
+0

Я ценю ваше творчество, но я думаю, что мое решение дешевле реализовать, хотя я не совсем уверен. Прошло менее двух секунд, чтобы работать против примерно 750 тыс. Строк. – PyNEwbie

+0

Если «дешевле реализовать» вы подразумеваете, что ваш подход работает быстрее, чем вы, вероятно, правы. Ваш подход также будет нарушен, если вместо 4 вместо 5. Если мое решение не нужно работать, я могу заставить его работать так быстро, как вы хотите. – RossFabricant

+0

Ну, одна проблема с моим решением заключается в том, что если есть когда-нибудь, что переменные не соответствуют порядку, то это не сработает. Но мое решение будет отлично работать с пятью или n переменными, я просто должен их определить. Наверное, я ошибался, нет ни одного лайнера. Я многому научился от вашего кода. – PyNEwbie

1

Если вы хотите, чтобы выбрать второй, третий и четвертый элементы каждой подсписка, это должно работать:

listINeed = [sublist[1:4] for sublist in biglist] 
+0

Ну, я не могу быть уверенным, какие они есть, и все, что я разместил, есть подсписок, поэтому мне может понадобиться 1 или десять единиц, которые обозначены только именами – PyNEwbie

+0

. Тогда вам нужно будьте более конкретными в своем вопросе ... Я действительно не понимаю, что именно вы пытаетесь сделать. –

0

Если я правильно понял ваш вопрос:

import re 
def getlines(ori): 
    matches = re.finditer(r'(<([1-4])[a-zA-Z]>.*)', ori) 
    mainlist = [] 
    sublist = [] 
    for sr in matches: 
     if int(sr.groups()[1]) == 1: 
      if sublist != []: 
       mainlist.append(sublist) 
      sublist = [] 
     else: 
      sublist.append(sr.groups()[0]) 
    else: 
     mainlist.append(sublist) 
    return mainlist 

... будет делать работу за вас, если вы чувствовали себя, как с помощью регулярных выражений.

В приведенной ниже версии все данные будут разбиты на подсписки (а не только на первые четыре в каждой группе), что может быть более полезным в зависимости от того, что еще нужно сделать для данных. Используйте David listINeed = [sublist [1: 4] для подписок в большом списке], чтобы получить первые четыре результата из каждого списка для указанной выше задачи.

import re 
def getlines(ori): 
    matches = re.finditer(r'(<(\d*)[a-zA-Z]>.*)', ori) 
    mainlist = [] 
    sublist = [] 
    for sr in matches: 
     if int(sr.groups()[1]) == 1: 
      print "1 found!" 
      if sublist != []: 
       mainlist.append(sublist) 
      sublist = [] 
     else: 
      sublist.append(sr.groups()[0]) 
    else: 
     mainlist.append(sublist) 
    return mainlist 
Смежные вопросы