我正在處理python中的列表和字符串。我有以下幾行字符串。根據初始字符解析重複的字符串行
ID abcd
AC efg
RF hij
ID klmno
AC p
RF q
我想作爲輸出:
abcd, efg, hij
klmno, p, q
這個輸出是基於該行的前兩個字符。我怎樣才能以有效的方式實現它?
我期待爲ID
標籤之間的每個條目輸出行的第二部分。
我正在處理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]只返回其他所有項目。
使用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]
OP實際上發佈了一個澄清,暗示這可能不是他們正在尋找的內容,儘管它對於該示例很有用。 –
是的。這似乎更像是你的回答是適當的問題。 – hanslovsky
如果線等於
['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'
]]
編輯:13年8月6日這是一個更好的一個沒有彈出();
zip(*[iter([line.split()[1] for line in alllines])]*3)
一個稍微不同的輸出
[(
'abcd', 'efg', 'hij'
), (
'klmno', 'p', 'q'
)]
您可以使用以下,這需要爲了顧及讓調換其字典的價值更有意義......
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']
我認爲使用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
基於在評論,這應該工作你的答案(如果我明白你在找什麼):
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」是否表示一組新數據的開始?該行的第一個字段總是與它們顯示的順序相同? – brianmearns
是的。 ID表示新數據的開始。每當ID來臨,數據收集需要開始,直到下一個ID遇到。 – sam
所以會輸出是什麼像 ID ABCD RF HIJ AC EFG 或者是輸入不可能? – TylerLubeck