我正在处理 python 中的列表和字符串。我有以下几行字符串。
ID abcd
AC efg
RF hij
ID klmno
AC p
RF q
我希望输出为:
abcd, efg, hij
klmno, p, q
此输出基于行中的前两个字符。我怎样才能以有效的方式实现它?
我希望为ID
标签之间的每个条目输出该行的第二部分。
我在解析问题时遇到了一些麻烦,但根据我的最佳猜测,这应该可以满足您的需求:
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] 只返回所有其他项目。
使用默认字典:
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]
您可以使用以下内容,其中考虑了顺序,以便转置字典的值更有意义......
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']
我认为 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
根据您在评论中的回答,这应该有效(如果我了解您在寻找什么):
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
直到您看到下一个数据集的开始,此时您输出前一个数据集。
当“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
如果行等于
['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'
)]