Python 列表 - 删除一些列表条目 [已关闭]

Python list - removing some list entries [closed]

提问人:Demions 提问时间:11/12/2023 最后编辑:Demions 更新时间:11/13/2023 访问量:82

问:


编辑问题以包括所需的行为、特定问题或错误以及重现问题所需的最短代码。这将有助于其他人回答这个问题。

12天前关闭。

我有一个目录,里面存储了多个配置文件,具有相同的命名逻辑。首先是备份日期,然后是设备名称。我想编写一个脚本,该脚本将遍历目录中的所有文件,并仅保留最早出现的备份文件。

脚本运行前的示例目录内容:

02-10-2023__Device1.tar
03-10-2023__Device2.tar
01-11-2023__Device1.tar
03-11-2023__Device2.tar
04-11-2023__Device1.tar
06-11-2023__Device2.tar
11-11-2023__Device2.tar
...

脚本运行后出现的结果:

02-10-2023__Device1.tar
03-10-2023__Device2.tar
01-11-2023__Device1.tar
03-11-2023__Device2.tar

脚本不应触及较旧的(10 月)备份,而应仅保留“最旧”的 11 月备份。在上面的例子中,只有两个设备,就我而言,有 100+ 个不同的设备。

我试图用它来填充目录内容列表。我使用日期时间来获取当前月份/年份数据。然后,我尝试使用 for 循环浏览列表并填充一个新列表,其中我只存储应使用 .我被困在尝试计算以某种方式结束的文件名的累积的步骤中。os.listdiros.remove

我走在正确的轨道上还是有更简单的方法?

到目前为止的代码:

import os, datetime

today=datetime.date.today()
month=today.month
year=today.year
date=str(str(month) + "-" + str(year))


files=os.listdir()

erase=[]


for file in files:
    if ????? and str(file[3:10]) == date:
        erase.append(file)
        os.remove(erase)

我只是不确定如何添加第一个 if 语句,该语句只会在现有文件已准备好的情况下添加文件。我确实尝试过使用“files.count(file[3:]) > 1”,但这不起作用。

python 列表

评论

3赞 wjandrea 11/13/2023
你到底是怎么被困住的?向我们展示您的代码。参见最小可重复示例。另请参阅 如何询问如何写一个好的标题等提示。
1赞 PortorogasDS 11/13/2023
@Demions 您能举例说明预期结果吗?我很难理解你在哪一步被卡住了。
0赞 Demions 11/13/2023
对不起,我将代码添加到原始帖子中。
0赞 Codist 11/13/2023
您的要求毫无意义。您说“脚本不应触及较旧的(10 月)备份,而只保留”最旧“的 11 月备份。如果您只想保留两个最早的 11 月备份,那么如何在不删除 10 月备份的情况下做到这一点?另外,当你说“11月”时,我假设你指的是当月

答:

2赞 Sash Sinha 11/13/2023 #1

也许你可以考虑将脚本分解为更小的、更容易推理的函数:

import datetime
import os
import subprocess
from collections import defaultdict


def get_device_name(filename: str) -> str:
  """Extracts the device name from the filename.

  Args:
    filename: The filename to extract the device name from.

  Returns:
    str: The extracted device name.
  """
  return filename.split("__")[1]


def group_files_by_device(files: list[str]) -> dict[str, list[str]]:
  """Groups files by device name.

  Args:
    files: List of file names.

  Returns:
    dict[str, list[str]]: Dictionary grouping filenames by device name.
  """
  grouped_files = defaultdict(list)
  for file in files:
    device_name = get_device_name(file)
    grouped_files[device_name].append(file)
  return grouped_files


def delete_newer_files(files: list[str], current_month: int,
                       current_year: int) -> None:
  """Deletes newer files, keeping only the oldest file for the current month and year.

  Args:
    files: List of file names for a specific device.
    current_month: Current month.
    current_year: Current year.
  """
  files_to_keep = []
  for file in files:
    file_date_str = file.split("__")[0]
    file_date = datetime.datetime.strptime(file_date_str, "%d-%m-%Y").date()
    if file_date.month == current_month and file_date.year == current_year:
      files_to_keep.append(file)
  oldest_file = min(
      files_to_keep,
      default="",
      key=lambda x: datetime.datetime.strptime(x.split("__")[0], "%d-%m-%Y"))
  for file in files_to_keep:
    if file != oldest_file:
      os.remove(file)


def main() -> None:
  """Main function to execute the script."""
  print("Before:")
  _print_tar_files()
  today = datetime.date.today()
  current_month = today.month
  current_year = today.year
  files = [file for file in os.listdir() if file.endswith('.tar')]
  grouped_files = group_files_by_device(files)
  for device_files in grouped_files.values():
    delete_newer_files(device_files, current_month, current_year)
  print("After:")
  _print_tar_files()


def _print_tar_files() -> None:
  tar_files = [file for file in os.listdir() if file.endswith('.tar')]
  print('\n'.join(sorted(tar_files)))


def _create_files_for_demonstration_purposes() -> None:
  file_names = [
      "02-10-2023__Device1.tar", "03-10-2023__Device2.tar",
      "01-11-2023__Device1.tar", "03-11-2023__Device2.tar",
      "04-11-2023__Device1.tar", "06-11-2023__Device2.tar",
      "11-11-2023__Device2.tar"
  ]
  for file_name in file_names:
    subprocess.run(['touch', file_name])


if __name__ == "__main__":
  _create_files_for_demonstration_purposes()
  main()

输出:

Before:
01-11-2023__Device1.tar
02-10-2023__Device1.tar
03-10-2023__Device2.tar
03-11-2023__Device2.tar
04-11-2023__Device1.tar
06-11-2023__Device2.tar
11-11-2023__Device2.tar
After:
01-11-2023__Device1.tar
02-10-2023__Device1.tar
03-10-2023__Device2.tar
03-11-2023__Device2.tar

评论

0赞 Demions 11/13/2023
它按应有的方式工作,结果符合预期。我将首先查看每个步骤(将花费 sime 时间;))。谢谢腰带!