输入是一个包含大量字符的字符串,我希望将此字符串拆分为带有特殊分隔符的字符串列表。
但我想简单地使用split
会产生新的字符串而不是分割原始输入字符串本身,在这种情况下它会消耗大量内存(它保证不会使用原始字符串)不再)。
那么有一种方便的方法可以做到这种破坏性的分裂吗?
情况如下:
input_string = 'data1 data2 <...> dataN'
output_list = ['data1', 'data2', <...> 'dataN']
我希望output_list中的data1
和input_string中的data1
(以及所有其他内容)共享相同的内存区域。
答案 0 :(得分:0)
在Python中,字符串是不可变的。这意味着任何更改字符串的操作都将创建一个新字符串。如果你担心内存(虽然这不应该是一个问题,除非你正在处理巨大的字符串),你总是可以用新的,修改过的字符串覆盖旧字符串,替换它。
您描述的情况虽然有点不同,因为split
的输入是一个字符串,输出是一个字符串列表。它们是不同的类型。在这种情况下,我只是创建一个包含split
输出的新变量,然后将旧字符串(这是分割函数的输入)设置为None
,因为您保证它不会是split_str = input_string.split(delim)
input_string = None
再次使用。
代码:
{{1}}
答案 1 :(得分:0)
唯一的选择是使用切片而不是split
来访问子串。您可以使用str.find
查找每个分隔符的位置。然而,这将是缓慢而且繁琐的。如果您可以使用split并使原始字符串退出范围,则值得付出努力。
你说这个字符串是输入的,所以你可能会考虑阅读较少数量的字符,这样你就可以处理更易于管理的字符串了。你真的需要同时在内存中的所有数据吗?
答案 2 :(得分:0)
也许Pythonic的方式是使用迭代器?这样,新的子串一次只能在内存中。基于 Splitting a string into an iterator:
import re
string_long = "my_string " * 100000000 # takes some memory
# strings_split = string_long.split() # takes too much memory
strings_reiter = re.finditer("(\S*)\s*", string_long) # takes no memory
for match in strings_reiter:
print match.group()
这样可以正常工作而不会导致内存问题。
答案 3 :(得分:0)
如果你正在谈论那些巨大的字符串,你无法忍受将它们放入内存中,那么可能会在字符串中运行一次(O(n),可能使用str.find
进行改进但我可以我不确定)然后存储一个包含slice
个对象的生成器会更节省内存吗?
long_string = "abc,def,ghi,jkl,mno,pqr" # ad nauseum
splitters = [','] # add whatever you want to split by
marks = [i for i,ch in enumerate(long_string) if ch in splitters]
slices = []
start = 0
for end in marks:
slices.append(slice(start,end))
start = end+1
else:
slices.append(slice(start,None))
split_string = (long_string[slice_] for slice_ in slices)