【问题标题】:python efficient replacement of strings in nested arraypython高效替换嵌套数组中的字符串
【发布时间】:2018-05-08 17:54:36
【问题描述】:

我有一个包含数千行字符串的 txt 文件。 每行以“#integer”的格式开始,例如“#100”。

我按顺序读取 txt 文件(第 1 行、第 2 行、第 3 行……)并得到一个我想要的特定数组,其中该数组是行号和连接到这些行的其他行的集合:

数组的形式为:

[ ['#355', '#354', '#357', '#356'], ['#10043', '#10047', '#10045'], ['#1221', '#1220', '#1223', '#1222', '#1224'], [...] ]

它可以包含数百个数字。 (这是因为我有一个数字数组以及与它们相关的更多“孩子”添加到每个子数组中。)

我在下面的函数之前读取了我的 txt 文件,这意味着我首先读取了我的 txt 文件,提取数字,然后将其作为数组传递给 extended_Strings 函数,该函数将每个数字替换为txt 文件中该数字行的实际字符串

def extended_strings(matrix,base_txt):
  string_matrix = matrix #new matrix to contain our future strings
  for numset in string_matrix:
    for num in numset:
      for line in base_txt:
        results = re.findall(r'^#\d+', line) #find the line # at start of string
        if len(results) > 0  and results[0] == num: #if we have a # line that matches our # in the numset
          index = numset.index(num) #find index of line # in the numset
          numset[index] = line #if we match line #'s, we replace the line # with the actual string from the txt

  return string_matrix

我正在努力让这个过程更短更高效,例如我在 txt 中有 150,000 个字符串,使用for line in base_txt 行扫描 txt 文件有数百万次。

有什么建议吗?

【问题讨论】:

  • 您能详细说明您的帖子吗?文本文件中的每一行是否以数字(整数)开头?如果是这样,这些行是否按这些数字排序?在使用“extended_strings”函数之前,您是否阅读过文本文件?请举例说明您的矩阵“[[[],[],...],[[],[],...],[[],[],...]...](级别1)"。据我了解,这是一个“numsets”列表(2 级)。下一个内部列表“num”(第 3 级)看起来像 nums 列表。另一方面,您的函数似乎将“num”作为单个数字处理,而不是作为列表处理。
  • Werner Wenzel - 我已经编辑了我的帖子以匹配您的问题。谢谢。

标签: python arrays string nested text-files


【解决方案1】:

我没有进行任何计量。但我相信这会有所帮助。 另一方面,还有很多改进的空间。

文本.txt:

#1 This is line #00001
#2 This is line #00002
#30 This is line #00030
#35 This is line #00035
#77 This is line #00077
#101 This is line #00101
#145 This is line #00145
#1010 This is line #01010
#8888 This is line #08888
#13331 This is line #13331
#65422 This is line #65422

代码:

import re

# reo = re.compile(r'^(#\d+)\s+(.*)\n$')           # exclude line numbers in "string_matrix"
reo = re.compile(r'^((#\d+)\s+.*)\n$')             # include line numbers in "string_matrix"

def file_to_dict(file_name):
    file_dict = {}
    with open(file_name) as f:
        for line in f:
            mo = reo.fullmatch(line)
            # file_dict[mo.group(1)] = mo.group(2) # exclude line numbers in "string_matrix"
            file_dict[mo.group(2)] = mo.group(1)   # include line numbers in "string_matrix"
    return file_dict

def extended_strings(matrix, file_dict):
    string_matrix = []
    for numset in matrix:
        new_numset = []
        for num in numset:
            new_numset.append(file_dict[num])
        string_matrix.append(new_numset)
    return string_matrix


matrix = [['#1010', '#35', '#2', '#145', '#8888'], ['#30', '#2'], ['#65422', '#1', '#13331', '#77', '#101', '#8888']]

file_dict = file_to_dict('text.txt')
string_matrix = extended_strings(matrix, file_dict)
for list_ in string_matrix:
    for line in list_:
        print(line)
    print()

【讨论】:

  • 感谢 Werner Wenzel,我正试图了解您在那里做了什么,但我不能完全理解。我查看了docs.python.org/2/library/re.html 以了解您的代码。那里没有 fullmatch() 方法...当我运行您的代码时,它说没有属性“fullmatch”...您能解释一下吗?我也不明白file_dict[mo.group(2)] = mo.group(1) 做了什么,尽管您发表了评论。
  • @Yafim Simanovsky:您似乎仍在使用 Python 2。“fullmatch”是 Python 3.4 的新属性。您可以尝试将“fullmatch”替换为“match”。 (应该可以,没试过。)“mo”是一个正则表达式匹配对象。 “mo.group(2)”包含行号,“mo.group(1)”包含整行。上述表达式在字典“file_dict”中创建一个条目,其中行号是值“整行”的键。
  • 谢谢。将其更改为 match 是正确的,但我仍然得到 AttributeError: 'NoneType' object has no attribute 'group',您认为 python 2 和 3.4 之间是否还有其他差异需要更改?
  • @Yafim Simanovsky:确实,这可能是 Python 2 / Python 3 不兼容,可能是不同的字符串概念。您可以尝试通过在 Unicode 前面加上“u”并在正则表达式后添加“UNICODE”标志来转换“text.txt”中的字符串。此外,Python 2 在“print”之后不使用括号。除了这些提示,我帮不了你。我只使用 Python 3。祝你好运!
【解决方案2】:

感谢 Werner Wenzel 的帮助, 我找到了适合我的解决方案,并想在这里分享:

import re

def file_to_dict(file_name):
    file_dict = {}
    with open(file_name) as f:
        for line in f:
            stg = re.findall("(.+)",line)
            stgNum = re.findall("#\d{1,10}",line)
            file_dict[stgNum[0]] = stg[0]
    return file_dict

def extended_strings(matrix, file_dict):
    string_matrix = []
    for numset in matrix:
        new_numset = []
        for num in numset:
            new_numset.append(file_dict[num])
        string_matrix.append(new_numset)
    return string_matrix


matrix = [['#1010', '#35', '#2', '#145', '#8888'], ['#30', '#2'], ['#65422', '#1', '#13331', '#77', '#101', '#8888']]

file_dict = file_to_dict('text.txt')
string_matrix = extended_strings(matrix, file_dict)
for list_ in string_matrix:
    for line in list_:
        print line

print "done"

【讨论】:

    猜你喜欢
    • 2014-04-09
    • 1970-01-01
    • 2010-09-27
    • 2011-11-13
    • 2015-04-25
    • 1970-01-01
    • 1970-01-01
    • 2017-03-20
    • 2013-01-19
    相关资源
    最近更新 更多