Python:在循环中修改存储在各种对象中的字符串

时间:2011-08-24 16:28:47

标签: python string reference iteration mutable

我有各种对象存储的字符串,例如a,b,c [2:7](即5个不同的字符串c [2],... c [6]),ds,es [:](即存储在es列表中的所有字符串)。我需要在代码中的不同位置循环遍历所有这些字符串,并在循环中修改这些变量。 (将修改后的字符串分配给新变量将不起作用,因为还有其他函数需要在原始变量中修改字符串。)如何在Python中有效地执行此操作?

如果我可以创建一个对字符串的引用列表,那么我可以一直迭代它:

str_ref_lst=[reference(a), reference(b), reference(d.s)]
str_ref_lst.extend[reference(c[2:7])]
str_ref_lst.extend[reference(e.s[:])]
...
for ref_strng in str_ref_lst:
  do_string_modifications1(dereference(ref_strng))
...
function_using_the_modified_variables1()
...
for ref_strng in str_ref_lst:
  do_string_modifications2(dereference(ref_strng))
...
function_using_the_modified_variables2()
etc

但是,我不知道Python中的reference()/ dereference()类似物(我想它在Python中也不是正确的方法)

4 个答案:

答案 0 :(得分:1)

您的do_string_modifications函数需要更改,以便它们返回新的字符串值,而不是尝试在适当的位置修改它(因为这是不可能的)。使用新函数修改列表,并在修改后将原始字符串引用重新分配给列表中的新值(如有必要):

str_lst = [a, b, d.s, c[2:7], e.s]
str_lst = [do_string_modifications1(x) for x in str_lst]
str_lst = [do_string_modifications2(x) for x in str_lst]
a, b, d.s, c[2:7], e.s = str_lst

答案 1 :(得分:1)

建议的答案应该是“使用字典”,但是如果你这样做:

class cls(object):
    pass

a = "<a>"
b = "<b>"
c = ["", "", "<c>"]
d = cls()
d.s = "<d.s>"
e = cls()
e.s = "<e.s>"

var_list = "a b c[2:7] d.s e.s".split()

for var in var_list:
    exec "%s+='Mod'" % var             # Modify the variables

print a,b,c,d.s,e.s
# >>> <a>Mod <b>Mod ['', '', '<c>', 'M', 'o', 'd'] <d.s>Mod <e.s>Mod
由于内部优化,

IIRC这种方式在Python 3.0中不起作用

使用切片,它应该有点像

import re

class cls(object):
    pass

def fn(var):      # function to apply to the strings
    return "[%s mod]" % var

a = "<a>"
b = "<b>"
c = "01234567890"
d = cls()
d.s = "<d.s>"
e = cls()
e.s = "<e.s>"

var_list = "a b c[2:7] d.s e.s".split()

for var in var_list:
    # Modify the variables
    try:
        # exec "%s='Hi there'" % var             # Modify the variables
        exec "%(var)s=fn(%(var)s)" % { "var": var }
    except TypeError:
        # Assume Slice...
        slice_ = re.findall("\[(\d+)\:(\d+)\]", var)[0]   # Get slice
        var_with_slice = var
        var = var.split("[")[0]                 # Remove slice
        # Look ma, I can code in Perl too! :)
        line = \
             "%(var)s=%(var)s[:%(slice1)s]+fn(%(var_with_slice)s)+%(var)s[%(slice2)s+1:]" % \
             { "var": var, "var_with_slice": var_with_slice, "slice1": slice_[0], "slice2": slice_[1] }
        # somewhat like c = c[:2] + fn(c[2:7]) + c[7+1:]
        exec line

print a,b,c,d.s,e.s
# >>> [<a> mod] [<b> mod] 01[23456 mod]890 [<d.s> mod] [<e.s> mod]

答案 2 :(得分:0)

你可以这样做。

def stringMod(inStr):
  return inStr.replace('f', 'g')

str_list = map(stringMod, str_list)

答案 3 :(得分:0)

你想要的一般性是不可能的。最大的障碍是您提供的切片操作c[2:7]e.s[:]。这些表达式不是左值,您无法分配它们。它们只是生成新的字符串值,您必须捕获它们或它们已经消失。

如果你只有lvalues(a,b,ds),你可以分配的表达式,你可以想到一些东西,但是用c [2:7]和es [:],这是不可能的。