我是Python的初学者,但我找不到问题的答案。我有一个包含一些数据的文件,我想从这个文件中获取数字。我的程序看起来像这样:
class Mojaklasa:
def przenumeruj_pdb(self):
nazwa=raw_input('Podaj nazwe pliku: ')
plik=open(nazwa).readlines()
write=open('out.txt','w')
for i in plik:
j=i.split()
if len(j)>5:
if j[0] == "ATOM":
write.write(j[5])
write.write("\n")
zapis.close()
文件中的第5个字段有一些从-19到100的数字,并且它的工作正常。但有时第5个字段的数字带有字母f.e. 28A并且只想要28.转换为int不起作用。我怎么能这样做?
答案 0 :(得分:3)
str.translate将删除任何字母:
s = "10A"
from string import ascii_letters
print(int(s.translate(None,ascii_letters)))
10
或者使用re:
import re
print(int(re.findall("\-?\d+",s))[0])
10
In [22]: s = "-100A"
In [23]: int(re.findall("\-?\d+",s)[0])
Out[23]: -100
In [24]: int(s.translate(None,ascii_letters))
Out[24]: -100
我还会改变你的代码:
class Mojaklasa: # unless there are more methods I would not use a class
def przenumeruj_pdb(self):
nazwa = raw_input('Podaj nazwe pliku: ')
with open(nazwa) as plik, open("out.txt", "w") as write: # with will close your iles
for line in plik: # iterate over file object
j = line.split()
if len(j) > 5 and j[0] == "ATOM": # same as nested if's
write.write("{}\n".format(j[5].translate(None, ascii_letters)))
答案 1 :(得分:1)
您可以使用格式正确的正则表达式替换大量逻辑。
for i in plik:
m = re.match(r'ATOM\s+.*?\s+.*?\s+.*?\s+.*?\s+(-?\d+)', i)
if m:
write.write(m.group(1) + '\n')
答案 2 :(得分:0)
这是一种全面改进的方法:
import re
class Mojaklasa:
def przenumeruj_pdb(self):
nazwa=raw_input('Podaj nazwe pliku: ')
with open(nazwa) as plik, open('out.txt','w') as zapis:
for i in plik:
j = i.split()
if len(j) <= 5: continue
if j[0] == "ATOM":
mo = re.match(r'\d+', j[5])
if mo is None: continue
zapis.write(mo.group() + '\n')
我没有改进您对标识符的选择(除了write
和zapis
之间的一些混淆),但改进包括(a)有用的缩进,(b)使用with
来打开文件(以便它们自动关闭),(c)仅通过re
(与Q最密切相关的一个)提取前导数字,(d)使用if/continue
行而不是缩进(因为&#34; flat比嵌套&#34;更好)。或许还有一些我可能会忘记: - )
我 还建议将j
重命名为line
,将i
重命名为fields
(或所选语言的等效内容){ {1}}和i
&#34;声音&#34;很像整数循环计数器等,这非常令人困惑: - )。