【问题标题】:Is there a way to work with files from a dictionary with similar names (numeric difference) in a loop? [duplicate]有没有办法在循环中处理具有相似名称(数字差异)的字典中的文件? [复制]
【发布时间】:2019-07-30 09:29:15
【问题描述】:

我想知道是否有办法在循环中使用具有相似名称的字典中的文件。

我有这个字典:

dcm = {}
for filename in os.listdir('./GMATfiles'):
    if fnmatch.fnmatch(filename,'DCM_hydra*.txt'):
       dcm[filename[:11]] = os.path.normpath(''.join(['./GMATfiles', '/', filename]))
       #print(dcm)

#OUT_INPUT
out={}
for filename in os.listdir('./GMATfiles'):
    if fnmatch.fnmatch(filename,'Out_hydra*.txt'):
       out[filename[:11]] = os.path.normpath(''.join(['./GMATfiles', '/', filename]))
       #print(out) 
#MATRIX_INPUT 
mtr={}
for filename in os.listdir('./GMATfiles'):
    if fnmatch.fnmatch(filename,'matrizr_hydra*.txt'):
       mtr[filename[:15]] = os.path.normpath(''.join(['./GMATfiles', '/', filename]))
       #print(mtr)

我从这些字典中得到的名字都是一样的,除了一个数字(例如:DCM_hydra01、DCM_hydra02、DCM_hydra03 等)

然后我需要在某些功能中使用字典中的这些文件:

IFOV1= gi.IFOV_generic(out['Out_hydra01'],mtr['matrizr_hydra01'], dcm['DCM_hydra01'],'ifovfile_hydra1', endpoint)
IFOV2= gi.IFOV_generic(out['Out_hydra02'],mtr['matrizr_hydra02'], dcm['DCM_hydra02'],'ifovfile_hydra2',endpoint)
.
.
.

有没有办法编写一个循环,让我获得这些 IFOV 函数而无需一个一个地编写它们?

有人已经告诉我使用zip()

dcm = {'f1': 'path_to_file'}
out = {'f1': 'path_to_file'}
mtr = {'f1': 'path_to_file'}

IFOV = []

for d, o, m in zip(dcm, out, mtr):
    IFOV.append(
        gi.IFOV_generic(out[o], mtr[m], dcm[d], endpoint)
    )

但我需要获取文件的名称('ifovfile_hydra*'),我不确定这段代码是否可以做到这一点。

【问题讨论】:

  • 您可以使用相同的键 - out["01"]mtr["01"]dcm["01"] 保留值,然后您可以更轻松地获取它们 - key = "01"out[key]mtr[key]、@987654331 @, 和"ifovfile_hydra" + int(key) 得到"ifovfile_hydra1""ifovfile_hydra" + key 如果你喜欢"ifovfile_hydra01"
  • 您可以在嵌套字典中将这些项目组合在一起,而不是拥有三个字典。格式类似于:{"hydra01": {"out": ..., "matrizr": ..., "DCM": ...}, "hydra02: {"out": ..., "matrizr": ..., "DCM": ...}, ...}

标签: python python-3.x loops dictionary


【解决方案1】:

字典中的“索引”是一个字符串,所以是的,我们可以用它做任何事情!

你得到的 sn-p 应该可以按预期工作,它实际上并不能在字符串中插入数字!只是对最终名称的一个小修正:

dcm = {'f1': 'path_to_file'}
out = {'f1': 'path_to_file'}
mtr = {'f1': 'path_to_file'}

IFOV = []

for d, o, m in zip(dcm, out, mtr):
    IFOV.append(
        gi.IFOV_generic(out[o], mtr[m], dcm[d], 'ifovfile_hydra'+o[-2:], endpoint)
    )

字典默认只遍历键。在你的情况下,文件名。

通过压缩,您可以将第一个字典的第一个键与第二个字典的第一个键和第三个字典的第一个键结合起来。

然后for 循环遍历这些 3 元素组并将它们的内容放入单独的变量中。它们仍然包含各自的文件名。

'ifovfile_hydra'+o[-2:] - o[-2:] 获取字符串 o 的最后两个字符('Out_hydra01'、'Out_hydra02'...)。

该代码的唯一问题是文件不按顺序排列(例如,第一个字典顺序是 03、01、02,而第二个和第三个是“正确的”)。这可以通过使dmc = dict(sorted(dcm.items()) 等来解决 - 在较新的 Python 中,字典的内容保持插入顺序,因此这个 sn-p 将字典转换为列表,对其进行排序并将其转换回字典(将在字典顺序,所以 "a10" "a02")。


另一件事是真正在字符串中填写数字。

for i in range(1, len(dcm)):
    IFOX.append(
        gi.IFOV_generic(out['Out_hydra{:02d}'.format(i)], met['matrizr_hydra{:02d}'.format(i)], dcm['DCM_hydra{:02d}'.format(i)],'ifovfile_hydra{:02d}'.format(i),  endpoint)
    )

:02d 部分表示它是一个 0 填充到 2 位数字。

【讨论】:

    【解决方案2】:

    我建议您直接在读取文件的同一循环中填充 IFOV。但是,如果您不想这样做,那么我建议改为创建一个字典,并且只遍历文件一次:

    from collections import defaultdict
    from pathlib import Path
    
    # If you're not on python 3.7, replace this with a function that makes a dict
    @dataclass
    class GmatFiles:
        dcm: str = ""
        out: str = ""
        mtr: str = ""
    
    
    files = defaultdict(GmatFiles)
    for filepath in Path("./GMATfiles".glob("*.txt"):
        if fnmatch.fnmatch(filename,'DCM_hydra*.txt'):
            files[filepath.name[9:11]].dcm = filepath
        elif nmatch.fnmatch(filename,'Out_hydra*.txt'):
            files[filepath.name[9:11]].out = filepath
        elif fnmatch.fnmatch(filename,'matrizr_hydra*.txt'):
            files[filepath.name[13:15]].mtr = filepath
    
    IFOV = []  
    for item in files.values():
        IFOV.append(
            dcm = files[k
            gi.IFOV_generic(item.out, item.mtr, item.dcm, endpoint)
        )
    

    【讨论】:

    • 您好,感谢您的回答!我试图这样做,但我得到了这个错误:``` dcm: str = "" SyntaxError: invalid syntax ``
    • @novich 你用的是什么版本的 Python?
    • Python 3.5.2,我应该升级它吗?
    • 如果可以的话,你应该这样做。但如果你不能,请阅读我说没有 3.7 就不能使用它的评论。相反,创建一个用键初始化和清空 dict 的函数。或者google如何在3.7之前制作一个数据类。 3.6 带有 f-strings,我会单独更新。
    猜你喜欢
    • 1970-01-01
    • 2021-07-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-02-21
    • 1970-01-01
    相关资源
    最近更新 更多