Замена Python не работает со списком - PullRequest
0 голосов
/ 31 декабря 2010

Мой код читает каталог и сохраняет имя файла с расширением в списке.То, что я пытаюсь сделать, это избавиться от расширения с заменой.Однако он не сохраняется в списке.

 print projectFilenames

 for f in projectFilenames:
  print f
  f = f.replace('.txt','')
  f = f.replace('.mdown','')
  f = f.replace('.markdown','')
  print f

 print projectFilenames

, и это мой вывод

['2010-10-30-markdown-example.txt', '2010-12-29-hello-world.mdown ',' 2011-1-1-tester.markdown ']
2010-10-30-markdown-example.txt
2010-10-30-markdown-example
2010-12-29-hello-world.mdown
2010-12-29-hello-world
2011-1-1-tester.markdown
2011-1-1-tester
['2010-10-30-markdown-example.txt', '2010-12-29-hello-world.mdown', '2011-1-1-tester.markdown']

Что я делаю не так?

Ответы [ 5 ]

6 голосов
/ 31 декабря 2010

Список не меняется, потому что вы не обновляете его.Вы никоим образом не касаетесь списка projectFilenames (ни строк в списке. Переменные Python не являются указателями). Вот один из способов сделать это:

newlist = []
for f in projectFilenames:
    f = f.replace('.txt','')
    f = f.replace('.mdown','')
    f = f.replace('.markdown','')
    newlist.append(f)

projectFilenames = newlist

Также посмотрите на os.pathМодуль, там есть функции, чтобы отрезать расширения файлов.os.path.splitext () специально.Таким образом, другой способ сделать это будет:

newlist = []
for f in projectFilenames:
    f = os.path.splitext(f)[0]
    newlist.append(f)

projectFilenames = newlist

Это, в свою очередь, может быть упрощено (и приведено в соответствие с PEP 8 ):

>>> import os
>>> project_filenames = ['2010-10-30-markdown-example.txt', '2010-12-29-hello-world.mdown', '2011-1-1-tester.markdown']
>>> project_filenames = [os.path.splitext(f)[0] for f in project_filenames]
>>> project_filenames
['2010-10-30-markdown-example', '2010-12-29-hello-world', '2011-1-1-tester']
4 голосов
/ 31 декабря 2010

фрагмент списка замена с использованием понимания списка (обновляет содержимое исходного списка):

l[:] = [f.replace('.txt','').replace('.mdown','').replace('.markdown','') for f in l]

splitext (предложено @lennart, @ sukhbir)

import os
l[:] = [os.path.splitext(f)[0] for f in l]

с использованием перечисления:

import os
for idx, filename in enumerate(l):
    newfilename = os.path.splitext(filename)[0]
    if newfilename != filename:
        l[idx] = newfilename

Анекдот: splitext()[0], str.replace('.txt') and str.split('.txt')[0] возвращает исходную строку без изменений, если она не имеет расширения или соответствия. (по крайней мере, в Python 2.6)

4 голосов
/ 31 декабря 2010

Вы заменяете объект f, а не projectFileNames, сделайте это так;

>>> [x.split(".")[0] for x in projectFileNames]
['2010-10-30-markdown-example', '2010-12-29-hello-world', '2011-1-1-tester']

Удаляет расширение.

2 голосов
/ 31 декабря 2010

Как упоминалось в других ответах, причина в том, что список имен файлов не меняется, потому что ваш код не меняет его. Есть несколько способов исправить это, в том числе создать новый список и заменить его оригиналом.

Я думаю, что самым простым подходом было бы просто изменить список, когда вы перебираете его элементы (но при этом вы должны быть осторожны, чтобы не изменять части списка, которые еще не видны). В Python есть встроенная функция enumerate(), которая упрощает кодирование такого рода задач. Что делает enumerate(), так это возвращает объект «итератор», который отсчитывает элементы по мере того, как он предоставляет каждый элемент из последовательности, поэтому счетчик также является индексом элемента в этой последовательности, и при необходимости этот индекс может использоваться для обновления соответствующий элемент списка.

Поскольку ваш код имеет дело с именами файлов, его можно еще улучшить, используя встроенный модуль с именем os.path, который доступен для работы с путями и именами файлов. Этот модуль имеет функцию splitext() для разбиения имен файлов на две части: «корень» и расширение. В документации он называется root, а не filename, потому что к нему может быть добавлен префикс информации о пути к каталогу.

Если ваш код был переписан с использованием enumerate() и os.path.splitext(), он может выглядеть примерно так:

import os
projectFilenames = ['2010-10-30-markdown-example.txt',
                    '2010-12-29-hello-world.mdown',
                    '2011-1-1-tester.markdown']

for i,f in enumerate(projectFilenames):
    root,ext = os.path.splitext(f)
    if ext in ('.txt', '.mdown', '.markdown'):
        projectFilenames[i] = root  # update filename list leaving ext off

print projectFilenames
# ['2010-10-30-markdown-example', '2010-12-29-hello-world', '2011-1-1-tester']

Если вы хотите удалить все расширения файлов, а не только конкретные, вы можете просто изменить if ext in ('.txt', '.mdown', '.markdown'): на if ext:.

1 голос
/ 31 декабря 2010

Такие операции с файлами всегда должны выполняться с os.path.splitext . Потому что его легче обслуживать, оно портативно и вам не нужно изобретать велосипед.

>>> os.path.splitext('/home/Desktop/foo.py')[0]
'/home/Desktop/foo'

Скажем, у вас есть список x, в котором есть все файлы:

[os.path.splitext(files)[0] for files in x]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...