2013-08-02 2 views
-5

Я работаю над списками и строками в python. У меня есть строки строки.синтаксический анализ повторяющихся строк строки на основе начальных символов

ID abcd 
AC efg 
RF hij 
ID klmno 
AC p 
RF q 

Я хочу, чтобы выход как:

abcd, efg, hij 
klmno, p, q 

Этот вывод основан на первых двух символов в строке. Как я могу достичь этого эффективным образом?

Я ищу для вывода второй части строки для каждой записи между тегами ID.

+3

Я думаю, нам нужно получить более подробную информацию. Каким образом он основан на первом символе в строке? Указывает ли «ИД» начало нового набора данных? Являются ли первые поля строки всегда в том же порядке, в каком они отображаются? – brianmearns

+0

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

+0

Так что же выход будет что-то вроде ID ABCD РФ Hij AC EFG или что вход не представляется возможным? – TylerLubeck

ответ

2

У меня возникли небольшие проблемы разбор вопроса, но в соответствии с моим лучшим предположением, это должно делать то, что вы ищете:

all_data = " ".join([line for line in file]).split("ID") 
return [", ".join([item.split(" ")[::2] for item in all_data])] 

В основном то, что вы делаете здесь сначала просто соедините все ваши данные (удалив новые строки), а затем разделите на ключевой фразу «ID»

После этого, если я правильно интерпретирую вопрос, вы хотите получить второе значение каждая пара. Эти пары ограничены пробелом (как и все в этом элементе из-за «.join в первой строке), поэтому мы просто переходим через этот список, захватывая каждый другой элемент.

В общем случае расколы имеют немного больше синтаксического сахара, чем обычно используется, а полный синтаксис: [start: end: step], поэтому [:: 2] просто возвращает каждый другой элемент.

+0

ahaa..i понимать. спасибо – sam

+0

Рад помочь! –

+0

no its helpful, потому что я новичок в этом, и я не понимаю, почему люди downvote, чем помогает. если бы я был мастером, тогда я бы даже не поставил вопрос. но помог. – sam

1

Используйте default dict:

from collections import defaultdict 
result = defaultdict(list) 
for line in lines: 
    split_line = line.split(' ') 
    result[split_line[0]].append(split_line[1]) 

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

print result[ID] 
+1

OP фактически опубликовал разъяснение, которое подразумевает, что это может быть не то, что они ищут, хотя это было бы полезно для примера. –

+0

Правда. Похоже, что ваш ответ подходит к вопросу. – hanslovsky

-1

Если строки равно

['ID abcd', 'AC efg', 'RF hij'] 

затем

[line.split()[1] for line in lines] 

Edit: Добавлено все ниже после того, как вниз голосов

Я не знаю, почему это было вниз проголосовали. Я думал, что код - это самый простой способ начать работу с информацией, предоставленной в то время. Возможно, это лучшее объяснение того, что я думал/думал, что данные были/есть?

если вход представляет собой список строк в повторяющейся последовательности, называемой alllines;

alllines = [ #a list of repeated lines of string based on initial characters 
'ID abcd', 
'AC efg', 
'RF hij', 
'ID klmno', 
'AC p', 
'RF q' 
] 

, то код есть;

[[line.split()[1] for line in lines] for lines in [[alllines.pop(0) \ 
for i in range(3)] for o in range(len(alllines)/3)]] 

В основном это говорит, создать подсписок три раскола [1] строки из всего списка всех строк для каждых трех строк в всем списке.

и выход:

[[ 
'abcd', 'efg', 'hij' 
], [ 
'klmno', 'p', 'q' 
]] 

Edit: 8-6-13 Это еще лучше без поп();

zip(*[iter([line.split()[1] for line in alllines])]*3) 

с немного другим выходом

[(
'abcd', 'efg', 'hij' 
), (
'klmno', 'p', 'q' 
)] 
1

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

from collections import OrderedDict 

items = OrderedDict() 
with open('/home/jon/sample_data.txt') as fin: 
    lines = (line.strip().partition(' ')[::2] for line in fin) 
    for key, value in lines: 
     items.setdefault(key[0], []).append(value) 

res = [', '.join(el) for el in zip(*items.values())] 
# ['abcd, efg, hij', 'klmno, p, q'] 
1

I думаю, используя itertools.groupby лучше всего подходит для такого разбора (сделать что-то до следующего знака X)

import itertools 

class GroupbyHelper(object): 
    def __init__(self): 
     self.state = None 

    def __call__(self, row): 
     if self.state is None: 
      self.state = True 
     else: 
      if row[0] == 'ID': 
       self.state = not self.state 

     return self.state 

# assuming you read data from 'stream' 

for _, data in itertools.groupby((line.split() for line in stream), GroupbyHelper()): 
    print ','.join(c[1] for c in data) 

выход:

$ python groupby.py 
abcd,efg,hij 
klmno,p,q 
1

На основании ваших ответов в комментариях, это должно работать (если я понимаю, что вы ищете):

data = None 
for line in lines: 
    fields = line.split(2) 
    if fields[0] == "ID": 
     #New set of data 
     if data is not None: 
      #Output last set of data. 
      print ", ".join(data) 
     data = [] 
    data.append(fields[1]) 

if data is not None: 
    #Output final data set 
    print ", ".join(data) 

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

1

Похоже, что вы хотели бы подгруппировать свои данные, когда в вашем ключе присутствует «ID». Решение Groupby может работать здесь, если вы знаете, как группировать ваши данные. Вот одна такая реализация, которая может сработать для вас.

>>> data=[e.split() for e in data.splitlines()] 
>>> def new_key(key): 
    toggle = [0,1] 
    def helper(e): 
     if e[0] == key: 
      toggle[:] = toggle[::-1] 
     return toggle[0] 
    return helper 

>>> from itertools import groupby 
>>> for k,v in groupby(data, key = new_key('ID')): 
    for e in v: 
     print e[-1], 
    print 


abcd efg hij 
klmno p q 
Смежные вопросы