【问题标题】:How to loop through dict using a counter如何使用计数器循环遍历字典
【发布时间】:2019-07-29 12:25:48
【问题描述】:

所以我正在尝试使用dict 进行排序循环。我想要做的是我的文件夹中有两个不同的 json 文件,我想为每个 json 文件应用每个 dict。这意味着json 文件 1 将是 dict 中的第一个,第二个 json 文件将是第二个 dict。

discordHooks = {'swedish': [
                'https://discordapp.com/api/webhooks/xxxxxxxxxxxxxx/ASDFDFGDSFGSDFG',
                'https://discordapp.com/api/webhooks/xxxxxxxxxxxxxxxx/EAAEFAEFAFlF'],
                'italian':[
                'https://discordapp.com/api/webhooks/xxxxxxxxxxxxxx/qwertyuiop',
                'https://discordapp.com/api/webhooks/xxxxxxxxxxxxxxxx/lkjahgfdsa']
            }

def sendToDiscord():
    directory = os.fsencode('./slack')
    for counters, file in enumerate(os.listdir(directory)):
        filename = os.fsdecode(file)
        if filename.endswith(".json"):
            with open('./slack/' + filename) as slackAttachment:
                 print(discordHooks.get('italian', [counters]))

我的想法是我希望它使用for counters, file in enumerate(os.listdir(directory)): 循环遍历每个 json 文件,我希望它发生的是第一个循环将是第一个 json 文件 == 应该打印出第一个 dict 值和下一个循环将是第二个字典值。

但是我不知道该怎么做,我也不想使用列表。

我如何能够遍历每个 dict 以便 json 文件的第一个循环将是 dict 的第一个值,而第二个循环将是 dict 的第二个值?


更新:

在我的文件夹中,我有两个 json 文件,第一个名为 Thrill.json,第二个文件是 HelloWorld.json,它们始终相同(不会随时添加新的 json 文件或删除 json)。

所以现在我正在使用代码:

discordHooks = {'swedish': [
                'https://discordapp.com/api/webhooks/xxxxxxxxxxxxxx/ASDFDFGDSFGSDFG',
                'https://discordapp.com/api/webhooks/xxxxxxxxxxxxxxxx/EAAEFAEFAFlF'],
                'italian':[
                'https://discordapp.com/api/webhooks/xxxxxxxxxxxxxx/qwertyuiop' #This going tobe applied for the first json,
                'https://discordapp.com/api/webhooks/xxxxxxxxxxxxxxxx/lkjahgfdsa' #this going to applied to second json]
            }

def sendToDiscord():
    directory = os.fsencode('./slack')
    for counters, file in enumerate(os.listdir(directory)):
        filename = os.fsdecode(file)
        if filename.endswith(".json"):
            with open('./slack/' + filename) as slackAttachment:
                 print(discordHooks.get('italian', [counters]))

所以基本上我想要做的是我希望第一个 json Thrill 打印出列表中的第一个值 https://discordapp.com/api/webhooks/xxxxxxxxxxxxxx/qwertyuiop ,当完成后,我们将通过第二个循环打印出https://discordapp.com/api/webhooks/xxxxxxxxxxxxxxxx/lkjahgfdsa

差不多就是这样,json 文件中有一些值,我稍后将在代码中应用(我还没有编写任何代码),但重要的是第一个 json 文件将具有来自意大利的第一个 webhook[0]基本上。第二个 json 文件将有第二个 webhook italian[1]。

我希望现在更清楚了! :)

【问题讨论】:

  • 列出列表中的所有文件路径,然后使用 with open 读取文件并使用 json.load 将该 dict 文件添加到您的 dic
  • 将字典的键设为文件名,不要使用枚举,即将'Hello'替换为"file_1.json"
  • @Dan 我不太明白我将如何完成它,如果你能做一个简单的代码示例,是否有可能?
  • @Thrillofit86 当然,添加了答案
  • 但是swedish...呢?

标签: python dictionary for-loop


【解决方案1】:

counters 是一个 int 并且您的 dict 的键是字符串(并且大多数是任意的 AFAICT),所以显然这不能按预期工作。

如果您根本不关心排序(如果目录内容和test dict 内容之间实际上没有真正的关系),您可以只使用 dict 的值作为列表:

test_list = list(test.values())
for i, fname in enumerate(os.listdir(...)):
    print("i : {} - fname : {} - value : {}".format(i, fname, test_list[i]))

请注意,如果目录中的条目数明显多于字典中的条目数,这将崩溃。

如果订购很重要,那么您还有其他一些问题......

第一个是 Python dicts 在 3.7.x 之前是无序的,所以如果你想要一个适用于旧 Python 版本的解决方案,你就不能使用普通的 dict - 你需要一个 collections.OrderedDict 或者只是一个简单的列表(key, value) 元组(您可以从中重建字典:vals = [("foo": "xxx"), ("bar: "yyy")]; test = dict(vals)

第二个问题是 os.listdir() 被明确记录为没有被订购(或者,更准确地说,是“任意订购”,这意味着即使连续两次调用来自同一进程的相同路径),除了最终手动对列表进行排序之外,您无能为力。

长话短说:如果目录的内容和您的数据之间存在任何关系,您必须自己以一种或另一种方式明确地实现这种关系。

编辑:鉴于您更新的问题,正确的解决方案是反过来解决问题:在 python 中配置 url->filename 映射,并从此映射中读取文件,即:

# We're going to need this to solve possible path issues
# (relying on the current working directory is a recipe for headaches)
# NB: we assume the json files are in _HERE/slack/)
_HERE = os.path.dirname(os.path.abspath(__file__))

discordHooks = {
    # list of `(url, filename)` pairs
    'italian':[
      ('https://discordapp.com/api/webhooks/xxxxxxxxxxxxxx/qwertyuiop', 'jsonfile1.json'),
      ('https://discordapp.com/api/webhooks/xxxxxxxxxxxxxxxx/lkjahgfdsa' , 'jsonfile2.js')
    ]
}

for url, filename in discordHooks["italian"]:
    path = os.path.join(_HERE, "slack", filename)
    if not os.path.exists(path):
        # Don't know how you want to handle the case...
        raise ValueError("file {} not found".format(path))
    print("url: {} - path: {}".format(url, path))

【讨论】:

  • 啊,我明白了!好吧,当我读完所有这些时,这很有意义。所以这意味着我需要重新研究我在这里想要完成的事情。也许我正在考虑把所有事情都做得很复杂,但我确实得到了更多的感谢!
【解决方案2】:
from pathlib import Path


def make_language_dict(thrill_hook: str, helloworld_hook: str):
    return {
        "Thrill": thrill_hook
        "HelloWorld": helloworld_hook
    }


discord_hooks = {
                    'swedish': make_language_dict(
                        thrill_hook='https://discordapp.com/api/webhooks/xxxxxxxxxxxxxx/ASDFDFGDSFGSDFG',
                        helloworld_hook='https://discordapp.com/api/webhooks/xxxxxxxxxxxxxxxx/EAAEFAEFAFlF'
                    ),
                    'italian':make_language_dict(
                        thrill_hook='https://discordapp.com/api/webhooks/xxxxxxxxxxxxxx/qwertyuiop',
                        helloworld_hook='https://discordapp.com/api/webhooks/xxxxxxxxxxxxxxxx/lkjahgfdsa'
                    ),
                }

def send_to_discord(directory: Path = Path(r"./slack")):
    for filepath in directory.glob("*.json"):
        with open(filepath.resolve()) as slack_attachment:
            for language in discord_hooks:
                 discord_hook = discord_hooks[language][filepath.stem]
                 print(discord_hook)
                 # Do stuff with the file and the discord_hook here...

【讨论】:

  • 我会试试看 :) 很快就会有结果
  • 这种解决方案的问题在于,您不能保证目录中的所有文件都将具有匹配的键......并且考虑到在目录中添加文件是多么容易,这在最好的。注意:并不是说解决方案是完全错误的,只是想强调可能的缺点......
  • @brunodesthuilliers 这是真的。我应该用try:except KeyError: 包装它吗?听起来这本字典作为配置文件可能更有意义。
  • 我现在更新了我的线程,添加了 discordHooks 也许现在循环遍历 dict 中的每个列表更容易?我无法弄清楚现在如何循环遍历字典内的列表。
  • @Thrillofit86 试试看,一开始我也更新了函数。
猜你喜欢
  • 1970-01-01
  • 2013-02-20
  • 2011-03-18
  • 1970-01-01
  • 2019-08-18
  • 1970-01-01
相关资源
最近更新 更多