如何解决首先检查字符串中每行的几位数,如果相等,则将这些行的一部分一起打印
例如,我有一个字符串
textstring= """
0000 Onn ch=1 n=60 v=50
0000 Onn ch=1 n=67 v=50
9600 Off ch=1 n=67 v=00
9600 Off ch=1 n=60 v=00
9600 Onn ch=1 n=62 v=50
9600 Onn ch=1 n=69 v=50
1920 Off ch=1 n=69 v=00
1920 Off ch=1 n=62 v=00
"""
当前四行数字相等时,例如9600
,如何一起打印67/60/62/69? (来自n=
之后的四行)
我尝试了以下类似方法,但是我认为它没有按预期运行
for i,char in enumerate(textstring):
if char=="O" and (textstring[i+1]=="f" or textstring[i+1]=="n"):
if textstring[i-5]==textstring[i+18] and textstring[i-4]==textstring[i+19] and textstring[i-3]==textstring[i+20] and textstring[i-2]==textstring[i+21]:
if char=="n" and textstring[i+1]=="=": #we look for "n=" in the text
note=int (textstring[i+2]+textstring[i+3]) #we restore the int from string after "n=",the use it as a note
note2=int (textstring[i+25]+textstring[i+26])
print(note)
print(note2)
解决方法
最好在词典中将具有相同代码的行分组,例如:
from collections import defaultdict
from pprint import pprint
d = defaultdict(list)
for line in textstring.splitlines():
cells = line.split()
if len(cells) > 1:
line_id,*values = cells
d[line_id].append(values)
pprint(d)
这将输出:
defaultdict(<class 'list'>,{'0000': [['Onn','ch=1','n=60','v=50'],['Onn','n=67','v=50']],'1920': [['Off','n=69','v=00'],['Off','n=62','v=00']],'9600': [['Off','v=50']]})
然后您可以轻松设置此字典的格式,例如:
for k,v in d.items():
print(k,"/".join(e[2][2:] for e in v))
输出为:
0000 60/67
9600 67/60/62/69
1920 69/62
,
通常,如果您有对象集合,则将对象放入类将始终帮助您操纵它们以执行所需的操作。
我在下面放置了示例代码,向您展示了一种非常基本的方法来将对象解析为一个类,然后使用该类来执行您想要的操作。
textstring = """
0000 Onn ch=1 n=60 v=50
0000 Onn ch=1 n=67 v=50
9600 Off ch=1 n=67 v=00
9600 Off ch=1 n=60 v=00
9600 Onn ch=1 n=62 v=50
9600 Onn ch=1 n=69 v=50
1920 Off ch=1 n=69 v=00
1920 Off ch=1 n=62 v=00
"""
# You appear to have a list of objects,so lets make a class that represents the object.
# The code inside here is very basic and assumes perfect input.
class MyThing():
def __init__(self,description: str):
fields = description.split()
self.Id: int = int(fields[0])
self.State: str = fields[1]
self.Channel: int = int(fields[2][3:])
self.N: int = int(fields[3][2:])
self.V: int = int(fields[4][2:])
def __str__(self):
# I use .format here but you can use f'' format strings in python >3.6
return '{:0>4d} {} ch={} n={} v={}'.format(self.Id,self.State,self.Channel,self.N,self.V)
if __name__ == '__main__':
objects = (MyThing(desc) for desc in textstring.splitlines() if desc != '')
# create a grouping so you can manipulate objects by matching id's
grouping = defaultdict(list)
for thing in objects:
grouping[thing.Id].append(thing)
for key in grouping.keys():
# print out the items that match the group
print('{:0>4d} {}'.format(key,'/'.join((str(thing.N) for thing in grouping[key]))))
输出:
0000 60/67
9600 67/60/62/69
1920 69/62
,
这是我使用itertools
的建议:
import itertools
textstring = """
0000 Onn ch=1 n=60 v=50
0000 Onn ch=1 n=67 v=50
9600 Off ch=1 n=67 v=00
9600 Off ch=1 n=60 v=00
9600 Onn ch=1 n=62 v=50
9600 Onn ch=1 n=69 v=50
1920 Off ch=1 n=69 v=00
1920 Off ch=1 n=62 v=00
"""
def header(line):
"""Return the first four digits. You can change how this is done."""
return line.split()[0] if line else None
def concatenate(group):
"""Return the 'n=' part. Be smarter about that,this is ugly."""
return [entry[16:18] for entry in group]
for head,group in itertools.groupby(lines,header):
group_list = concatenate(group)
print("/".join(group_list))
这将产生输出:
60/67
67/60/62/69
69/62
为满足您的需求,我会在末尾添加一个filter
:
filter = "9600"
for head,header):
if head != filter:
continue
group_list = concatenate(group)
print("/".join(group_list))
输出:
67/60/62/69
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。