2010-06-02 3 views
0

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

a score=216 expect=1.05e-06 
a score=180 expect=0.0394 

То, что я хочу сделать, это иметь подпрограмму , анализирующие их и возвращает 2 значения (оценка и ожидать) для каждой строки.

Однако эта функция шахты, кажется, не работает:

def scoreEvalFromMaf(mafLines): 
    for word in mafLines[0]: 
     if word.startswith("score="): 
      theScore = word.split('=')[1] 
      theEval = word.split('=')[2] 
      return [theScore, theEval] 
    raise Exception("encountered an alignment without a score") 

Пожалуйста, советы, что это правильный способ сделать это?

+0

Как и в сторону, никогда не поднимать 'Exception', так как невозможно, чтобы поймать его здраво Всегда поднимать что-то более узкое, как' ValueError' или что-то, что вы создаете. –

ответ

2

Похоже, вы хотите разделить каждую строку на пробелы и разобрать каждый фрагмент отдельно. Если mafLines является строкой (т.е. одна строка из .readlines():..

def scoreEvalFromMafLine(mafLine): 
    theScore, theEval = None, None 
    for word in mafLine.split(): 
     if word.startswith("score="): 
      theScore = word.split('=')[1] 
     if word.startswith("expect="): 
      theEval = word.split('=')[1] 

    if theScore is None or theEval is None: 
     raise Exception("Invalid line: '%s'" % line) 

    return (theScore, theEval) 

, как вы делали это будет перебирать каждый символ в первой строке (так как это список строк), а не на каждом пространстве

+0

@AB: Привет, Тони, спасибо. Но я также получаю то же сообщение '' error: объект «list» не имеет атрибута «split» «», используя ваш фрагмент. – neversaint

+0

Тогда 'mafLines' - список списков, а не список строк. Я предполагал, что 'mafLines' был выведен из' .readlines() 'или подобным, но если это не так, вам нужно будет уточнить, что это такое или как вы его создаете. –

+0

Я исправил его, используя: '' для слова в mafLine [0]: «' – neversaint

2

Если mafLines, если список строк, и вы хотите посмотреть только на первый, .split, что линия, чтобы получить слова. Например:

def scoreEvalFromMaf(mafLines): 
    theScore = None 
    theEval = None 
    for word in mafLines[0].split: 
     if word.startswith('score='): 
      _, theScore = word.partition('=') 
     elif word.startswith('expect='): 
      _, theEval = word.partition('=') 
    if theScore is None: 
     raise Exception("encountered an alignment without a score") 
    if theEVal is None: 
     raise Exception("encountered an alignment without an eval") 
    return theScore, theEval 

Обратите внимание, что это будет возвращать кортеж с двумя строки пунктов; если вы хотите Int и поплавок, например, вам нужно изменить последнюю строку на

return int(theScore), float(theEval) 

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

+0

@AM: Привет, Алекс, спасибо. Но я получаю это m essage '" error: объект 'list' не имеет атрибута 'split' ''. BTW, это правильный способ сохранения вывода функции: '[score, exp] = scoreEvalFromMaf (maf)' – neversaint

+1

Похоже, что mafLines - это список списков, а не список строк. Как вы его генерируете? В этом коде есть пара ошибок: вам нужно использовать '.split()' (т. Е. Это вызов функции), а также использовать 'word.split ('=')' вместо слова. partition ('=') ' –

+1

@neversaint, вам определенно нужно уточнить, что такое таинственное' mafLines' ** ** - предположительно список списков, как говорит Энтони (учитывая полученное сообщение об ошибке), но не зная как вы его построили, по сути, невозможно «читать ваш разум» и просто богодушить, что за штуки, из воздуха. Да, как только вы уточните этот момент, вы можете (если хотите) поместить эти бесполезные скобки вокруг «score, exp» в правой части задания. –

1

обязательное и, возможно, неуместны регулярное_выражение решение:

import re 
def scoreEvalFromMaf(mafLines): 
    return [re.search(r'score=(.+) expect=(.+)', line).groups() 
      for line in mafLines] 
+1

Это будет взорваться для недопустимого ввода (хотя это поведение может быть тем, что вы хотите). Поворот вашего '(. +)' В '(. *)' Помогает поймать пустые значения, но все равно умрет за действительно изворотливый ввод. –

+0

Достаточно. Это просто быстрый и грязный пример альтернативной стратегии. – harto

Смежные вопросы