-5

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

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

我希望输出为:

abcd, efg, hij
klmno, p, q  

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

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

4

7 回答 7

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] 只返回所有其他项目。

于 2013-08-02T14:26:53.480 回答
1

使用默认字典

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]
于 2013-08-02T14:26:48.917 回答
1

您可以使用以下内容,其中考虑了顺序,以便转置字典的值更有意义......

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']
于 2013-08-02T14:29:59.353 回答
1

我认为 usingitertools.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
于 2013-08-02T14:31:38.153 回答
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直到您看到下一个数据集的开始,此时您输出前一个数据集。

于 2013-08-02T14:35:10.753 回答
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
于 2013-08-02T14:41:12.603 回答
-1

如果行等于

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

然后

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

编辑:在投票后添加了下面的所有内容

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

如果输入是重复序列的字符串列表,称为 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'
]]

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

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

输出略有不同

[(
'abcd', 'efg', 'hij'
), (
'klmno', 'p', 'q'
)]
于 2013-08-02T14:28:01.553 回答