python

时间:2016-02-11 16:38:00

标签: python python-2.7

当我调试一小段代码时,我注意到了一些意想不到的事情:

循环遍历文件名以移除数字的for循环,通过查看字符串的每个字符并替换它,似乎在循环的第一遍中存在文件名的打印并循环通过那些如果像我在代码中那样对传递给循环的字符串进行更改,那么python仍然会查找字符串中的字母开头。

我刚刚发现(对我自己)for循环的一个基本特征,还是这只是我的代码产生的奇怪之处?

short_list = ['1787cairo.jpg', '237398rochester.jpg']
print short_list
for entry in short_list:
    entry_pos = short_list.index(entry)
    for char in entry:
        print entry, char, ord(char)
        if ord(char) in range (48,58):
            entry = entry.replace(char,'')
        print entry
    short_list[entry_pos] = entry              
print short_list

2 个答案:

答案 0 :(得分:7)

这里的要点是Python变量实际上只是指向对象的名称。执行for char in entry时,for循环会迭代entry恰好指向的任何内容;如果你然后重新分配entry指向别的东西,那么迭代器就不会知道。

请注意,如果entry恰好是一个可变对象(如列表),并且您对该对象中的项进行了变异,则迭代器所看到的值将更改;再次,这是因为迭代器指向对象本身。

真的,你的代码过于复杂;您应该使用更改的项目构建新列表,而不是保留索引并替换列表中的项目:

new_list = []
for entry in short_list:
    new_entry = ''
    for char in entry:
        if ord(char) not in range (48,58):
            new_entry += char
    new_list.append(new_entry)

这可以进一步缩短为嵌套列表理解:

[''.join(char for char in entry if ord(char) not in range (48,58)) for entry in short_list]

(并且,作为进一步改进,ord(char)的检查可以由char.isdigit()替换。)

答案 1 :(得分:0)

尝试改为

from string import digits

def remove_chars(s, bad_chars):
    """
    Return `s` with any chars in `bad_chars` removed
    """
    bad_chars = set(bad_chars)
    return "".join(ch for ch in s if ch not in bad_chars)

short_list = ['1787cairo.jpg', '237398rochester.jpg']
short_list = [remove_chars(entry, digits) for entry in short_list]

给出了

['cairo.jpg', 'rochester.jpg']