用Python 3.4将文本文件过滤成列表

3

我在将一个 .txt 文件过滤成子列表并将其转换为目录时遇到了一些问题,这与 IT 技术有关。以下是来自 text.txt 的示例:
A2.-B4-...C4-.-.D3-..E1.F4..-.G3--.H4....75--...85---..95----.05-----.6.-.-.-,6--..--?6..--..!5..--.
它没有空格或换行符,基本上是一行文本。
A2.- 表示符号 'A' 在摩尔斯电码中有 2 个字符,它们是 .- 等等。

我想做的是将这个长字符串拆分成子列表,然后将它们压缩成一个目录,以便我可以使用它来制作一个摩尔斯电码翻译器。我希望程序能够实现以下功能:创建一个包含键 A、B、C、...、?、. 的列表 keyList,以及另一个包含键值的列表 valueList。
但由于键不全是字母,我在遍历整个文件时遇到了问题。
我尝试过的方法如下:

import re
r = open("text.txt", "r")
ss = r.read()    
p = re.compile('\w'+'\w')
keyList = p.findall(ss)
ValueList = p.split(ss)
print(keyList)
print(ValueList)


keyList = ['A2', 'B4', 'C4', 'D3',..., '75', '85', '95', '05']
ValueList = ['', '.-', '-...', '-.-.', '-..', space , !5..--.']

如您所见,valuelist 无法正确分割,因为 '\w'+'\w' 只会匹配字母数字字符。我尝试更改 re.compile 的参数,但没有找到有效的解决方法。有什么帮助吗?re.compile 是最好的方法吗?还是有其他方法可以过滤文本?

编辑:期望/想要的输出:

keyList = ['A','B','C','D',...,'.','?',',']
ValueList = ['.-','-...','-.-.','-..',...,'.-.-.-','..--..','--..--']

你只需要字母吗?像 AB,..?你能把期望的输出加到问题里吗? - Mazdak
是的,基本上这就是我想要的,但是列表不仅包含字母,甚至'.'也有莫尔斯码,即.-.-.-<br/>所以我也想让'.'成为一个键,并且它的值为'.-.-.-'。 - kroneckersdelta
那么数字呢?最好是添加所需的输出! - Mazdak
4个回答

1

如果你想制作一个编码器/解码器,最好使用字典而不是列表。

至于解析它,直接而朴素的方法可能是最好的选择。

result = {}
with open('morse.txt', 'r') as f:    
    while True:    
        key = f.read(1)                                                   
        length_str = f.read(1)                                            

        if len(key) != 1 or len(length_str) != 1:                         
            break                                                         

        try:                                                              
            length = int(length_str)                                      
        except ValueError:                                                
            break                                                         

        value = f.read(length)                                            

        if len(value) == length:                                          
            result[key] = value                                           

for k, v in result.items():
    print k, v    

结果为:
A .-
! ..--.                                                                   
C -.-.                                                                    
B -...                                                                    
E .                                                                       
D -..                                                                     
G --.                                                                     
F ..-.                                                                    
H ....                                                                    
, --..--                                                                  
. .-.-.-                                                                  
0 -----                                                                   
7 --...                                                                   
9 ----.                                                                   
8 ---..                                                                   
? ..--..

1

你可以尝试以下内容:

items = re.findall(r'(.\d)([\.-]+)', ss)
keys = [s[0][0] for s in items]
values = [s[1] for s in items]

我得到了:

>>> keys
['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', '7', '8', '9', '0', ',', '?', '!']
values
['.-', '-...', '-.-.', '-..', '.', '..-.', '--.', '....', '--...', '---..', '----.', '-----.', '--..--', '..--..', '..--.']

这比我的答案简洁得多。我猜长度除了作为分隔符之外没有任何意义! - Cuadue

0

Cuadue的答案类似,我会使用循环来解析它,但我会以相反的顺序进行:

morse_str = 'A2.-B4-...C4-.-.D3-..E1.F4..-.G3--.H4....75--...85---..95----.05-----.6.-.-.-,6--..--?6..--..!5..--.'
morse_list = list(morse_str)
morse_dict = {}
while morse_list:
    morse = ''
    while True:
        sym = morse_list.pop()
        try:
            int(sym)
        except ValueError:
            morse += sym
        else:
            key = morse_list.pop()
            morse_dict[key] = morse[::-1]
            break

0

如果要查找键,您可以在正则表达式中使用正向先行断言

>>> s = 'A2.-B4-...C4-.-.D3-..E1.F4..-.G3--.H4....75--...85---..95----.05-----.6.-.-.-,6--..--?6..--..!5..--.'
>>> keys = re.findall(r'[\w|\W](?=\d\W)',s)
['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', '7', '8', '9', '0', '.', ',', '?', '!']

Regular expression visualization

Debuggex演示

由于您的键和值中都有像,。这样的非字母字符,因此您不能只使用一个re函数来获取预期的值,您可以使用该模式与split()函数一起根据您的键拆分字符串,然后您将只有一个数字作为前导生成的预期值输出,然后使用re.sub()删除该数字:

>>> values = [re.sub('\d','',i) for i in re.split(r'[\w|\W](?=\d)',s) if len(i)]
['.-', '-...', '-.-.', '-..', '.', '..-.', '--.', '...', '--..', '---.', '----', '-----', '.-.-.-', '--..--', '..--..', '..--.']

因此,作为一个重要的事情,你必须让keysvalues具有相同的len

>>> len(keys)
16
>>> len(values)
16

最后将它们压缩成zip文件:

>>> dict(zip(keys,values))
{'A': '.-', '!': '..--.', 'C': '-.-.', 'B': '-...', 'E': '.', 'D': '-..', 'G': '--.', 'F': '..-.', 'H': '...', ',': '--..--', '.': '.-.-.-', '0': '-----', '7': '--..', '9': '----', '8': '---.', '?': '..--..'}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接