简体   繁体   English

如何自动迭代每个列表项并执行唯一 function

[英]How to automatically iterate over each list item and perform a unique function

I have various files in one directory;我在一个目录中有各种文件;

  • foo.1001.exr foo.1001.exr
  • foo.1002.exr foo.1002.exr
  • bar.1001.exr bar.1001.exr
  • bar.1002.exr bar.1002.exr

I'd like to rename all of the files in this directory, but in the case of this directory holding more than one type of image sequence I would like to iterate over them one at a time so I don't overwrite anything and only end up with 2 files.我想重命名这个目录中的所有文件,但是如果这个目录包含不止一种类型的图像序列,我想一次迭代一个,这样我就不会覆盖任何东西,只会结束最多2个文件。

I was planning on separating them by the first part of the filename and adding them to a list, to get the number of variations.我打算用文件名的第一部分将它们分开并将它们添加到列表中,以获得变化的数量。 What I am unsure of is how to have the function iterate over newList[0], newList[1] and so on, automatically.我不确定的是如何让 function 自动迭代 newList[0]、newList[1] 等等。 It would need to be robust to cater to an indefinite amount of list items.它需要足够健壮才能满足无限量的列表项。

The output should be: output 应该是:

  • foo_test.1001.exr foo_test.1001.exr
  • foo_test.1002.exr foo_test.1002.exr
  • bar_test.1001.exr bar_test.1001.exr
  • bar_test.1002.exr bar_test.1002.exr

The code below is not indicative of the renaming task, it was just to start planning how to iterate procedurally over the list items.下面的代码并不表示重命名任务,它只是开始计划如何以程序方式遍历列表项。

import os

dir = "/test/"

# File formats
imageFileFormats = (".exr", ".dpx")

fileName = []
for file in os.listdir(dir):
    for ext1 in imageFileFormats:
        if ext1 in file:
            fileName.append(file.split('.')[0])

newList = list(set(fileName))
newList.sort()

for file in os.listdir(dir):
    for ext1 in imageFileFormats:
        if ext1 in file:
            if newList[0] in file:
                print (file)

This seems like a bit of an XY problem - instead of renaming the file collection in place, causing the potential for conflicts, have you considered creating a new folder to move all the files to, renaming them in the process?这似乎是一个 XY 问题 - 而不是在适当的位置重命名文件集合,从而导致潜在的冲突,您是否考虑过创建一个新文件夹以将所有文件移动到其中,并在此过程中重命名它们? Once complete, you can move them back to the original location, avoiding the problem altogether.完成后,您可以将它们移回原来的位置,从而完全避免该问题。

As long as you have a mapping from old name to new name for each file that won't cause a conflict in the final result, the order of moving the files then won't matter.只要每个文件都有从旧名称到新名称的映射,不会导致最终结果发生冲突,那么移动文件的顺序就无关紧要了。

And as long as the target folder is on the same volume, a move operation is basically a renaming anyway, so there's no space issues or performance problems.只要目标文件夹在同一卷上,移动操作基本上就是重命名,因此不存在空间问题或性能问题。

So, something like:所以,像这样:

from pathlib import Path

def do_rename(fn):
    # whatever non-conflicting renaming operation you need
    p = Path(fn)
    return p.parent / f'{p.stem}_renamed{p.suffix}'


def do_reverse_rename(fn):
    # just including the reverse of the above here for testing purposes
    p = Path(fn)
    return p.parent / f'{p.stem[:-8]}{p.suffix}' if p.stem.endswith('_renamed') else p


def safe_rename_all(location, rename_func):
    p = Path(location)

    # come up with a folder name that doesn't exist, right next to the original
    n = 1
    while (p.parent / f'{p.name}_{n}').is_dir():
        n += 1

    # create the new temporary folder
    (target := p.parent / f'{p.name}_{n}').mkdir()

    # move all the files into the new folder, this example matches *all* files
    #  of course you could filter, etc.
    for fn in p.glob('*'):
        new_fn = rename_func(fn)
        fn.rename(target / new_fn.name)  # move to the temporary location

    # once done, move everything back and delete the temporary folder
    for fn in target.glob('*'):
        fn.rename(p / fn.name)
    target.rmdir()


safe_rename_all('some/folder/with/files', do_rename)
# can be undone with safe_rename_all('output', do_reverse_rename)

Some considerations might be to not create a folder right next to the original (to avoid rights issues, etc.) but instead create a temporary folder on the same volume using the standard library tempfile .一些注意事项可能是不要在原始文件旁边创建一个文件夹(以避免权限问题等),而是使用标准库tempfile在同一卷上创建一个临时文件夹。 And you were filtering for certain suffixes, so that's easy to add.您过滤了某些后缀,因此很容易添加。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM