从列表中的字符串中删除有问题的字符

时间:2013-05-17 19:05:31

标签: python python-2.7

要解析的示例数据(unicode字符串列表):

[u'\n', u'1\xa0', u'Some text here.', u'\n', u'1\xa0', u'Some more text here.', 
u'\n', u'1\xa0', u'Some more text here.']

我想从这些字符串中删除\xa0

修改 目前的方法不起作用:

def remove_from_list(l, x):
  return [li.replace(x, '') for li in l]

remove_from_list(list, u'\xa0')

我仍然得到完全相同的输出。

3 个答案:

答案 0 :(得分:5)

每个版本的代码都存在不同的问题。让我们从这开始:

newli = re.sub(x, '', li)
l[li].replace(newli)

首先,newli 已经您想要的行 - 这就是re.sub的作用 - 所以您根本不需要replace。只需指定newli

其次,l[li]不起作用,因为li是该行的,而不是 index


在这个版本中,它是一个更微妙的:

li = re.sub(x, '', li)

re.sub正在返回一个新字符串,您将该字符串分配给li。但这不会影响列表中的任何内容,只是说“li不再引用列表中的当前行,它现在引用这个新字符串”。


只有替换列表元素才能获取索引,以便您可以使用[]运算符。为此,您需要使用enumerate

所以:

def remove_from_list(l, x):
  for index, li in enumerate(l):
    l[index] = re.sub(x, '', li)
  return l

但实际上,您可能想要使用str.replace - 只是您想要使用它而不是re.sub

def remove_from_list(l, x):
  for index, li in enumerate(l):
    l[index] = li.replace(x, '')
  return l

如果x是正则表达式中的特殊字符,那么您不必担心会发生什么。


此外,在Python中,您几乎不希望就地修改对象,也返回它。修改它并返回None,或返回对象的新副本。所以,要么:

def remove_from_list(l, x):
  for index, li in enumerate(l):
    newli = li.replace(x, '')
    l[index] = newli

......或:

def remove_from_list(l, x):
  new_list = []
  for li in l:
    newli = li.replace(x, '')
    new_list.append(newli)
  return new_list

你可以简单地将后者用于列表理解,就像unutbu的回答一样:

def remove_from_list(l, x):
  new_list = [li.replace(x, '') for li in l]
  return new_list

事实上,第二个更容易编写(不需要enumerate,有一个方便的快捷方式等)并非巧合 - 它通常是你想要的,所以Python使它变得容易。


我不知道如何更清楚,但最后一次尝试:

如果选择返回列表的固定新副本而不是就地修改列表的版本,则不会以任何方式修改原始列表。如果要使用已修复的新副本,则必须使用该函数的返回值。例如:

>>> def remove_from_list(l, x):
...     new_list = [li.replace(x, '') for li in l]
...     return new_list
>>> a = [u'\n', u'1\xa0']
>>> b = remove_from_list(a, u'\xa0')
>>> a
[u'\n', u'1\xa0']
>>> b
[u'\n', u'1']

你的实际代码将所有内容转换为1个字符和0个字符的字符串列表的问题是你实际上没有一个字符串列表,你有一个字符串是一个repr字符串列表。因此,for li in l表示“对于字符串li中的每个字符l,而不是for each string li in the list l`。

答案 1 :(得分:3)

另一个选择,如果你只对ASCII字符感兴趣(正如你提到characters,但这也适用于发布的例子的情况):

[text.encode('ascii', 'ignore') for text in your_list]

答案 2 :(得分:1)

您可以使用list comprehensionstr.replace

>>> items
[u'\n',
 u'1\xa0',
 u'Some text here.',
 u'\n',
 u'1\xa0',
 u'Some more text here.',
 u'\n',
 u'1\xa0',
 u'Some more text here.']
>>> [item.replace(u'\xa0', u'') for item in items]
[u'\n',
 u'1',
 u'Some text here.',
 u'\n',
 u'1',
 u'Some more text here.',
 u'\n',
 u'1',
 u'Some more text here.']