根据初始字符解析重复的字符串行

时间:2013-08-02 14:19:48

标签: python string list

我正在使用python中的列表和字符串。我有以下几行字符串。

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

我希望输出为:

abcd, efg, hij
klmno, p, q  

此输出基于行中的前两个字符。我怎样才能以有效的方式实现它?

我希望为ID代码之间的每个条目输出该行的第二部分。

7 个答案:

答案 0 :(得分:2)

我在解析这个问题时遇到了一些麻烦,但根据我的最佳猜测,这应该是你想要的:

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

基本上你在这里做的是首先将所有数据连接在一起(删除换行符)然后拆分你的关键词“ID”

之后,如果我正确地解释了这个问题,那么你需要获得每对的第二个值。这些对是空格分隔的(由于第一行中的“.join”,该项目中的所有内容都是如此),因此我们只需逐步浏览该列表,抓住其他项目。

一般来说,splits的语法糖比通常使用的要多一些,完整的语法是:[start:end:step],所以[:: 2]只返回其他每一项。

答案 1 :(得分: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]

答案 2 :(得分: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']

答案 3 :(得分:1)

我认为使用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

答案 4 :(得分: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,直到您看到下一个数据集的开始,此时您输出以前的数据集。

答案 5 :(得分: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

答案 6 :(得分:-1)

如果行等于

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

然后

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

修改:在投票后添加以下所有内容

我不确定为什么这会被投票。我认为代码是开始使用当时提供的信息的最简单方法。也许这是对我认为/认为数据是什么的更好的解释?

如果input是重复序列中的字符串列表,则称为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)]]

这基本上说,从整个列表中每三个字符串的所有字符串的整个列表中创建三个split [1]字符串的子列表。

并输出;

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

编辑:8-6-13 这是一个更好的没有pop();

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

输出略有不同

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