【问题标题】:Python - find first dictionary key in templatePython - 在模板中找到第一个字典键
【发布时间】:2017-01-04 20:37:21
【问题描述】:

我试图在 for 循环中的模板中显示我的字典键和值,但我不想显示第一个键。 最好的方法是什么? 我想使用类似的东西

dictionary.keys()[0]

但我不能在模板中做到这一点。 或者可能在 for 循环中添加计数器(不确定如何在下面的循环中执行此操作) 这是我显示字典的循环-

 {% for year, durations in durationDict.items %}
      <optgroup label={{ year }}>
      {% for duration in durations %}
           <option data-from-date="{{ duration.from_date }}" data-to-date="{{ duration.to_date }}" value={{ duration.duration_id }}>{{ duration.from_date }}
                                - {{ duration.to_date }}</option>
      {% endfor %}
 {% endfor %}

【问题讨论】:

  • first dictionary key 是什么意思? Python 字典是一个哈希表,它没有排序,所以键没有顺序。
  • 字典中没有“第一个键”。如果相同的代码在不同的机器上运行,您可以执行dict.keys()[0] 的事实可能会给您带来令人惊讶的不同结果。它可以在您的本地机器上完美运行,而不是在生产中,它可能在今天运行,但明天不行。如果您想要序列,请使用元组列表。
  • 也许你想了解哈希表是什么样子的:en.wikipedia.org/wiki/Hash_table
  • 正如@ShangWang 指出的那样,python 的 dicts 不会保留顺序——如果您使用其他建议之一,您可能会忽略错误的键。 collections 标准库包含一个 OrderedDict 类,它可以满足您的需求。
  • 我认为如果不知道您是要排除第一个 key (顺序无关)还是第一个 year (顺序相关的)。如果您只是想排除第一个键,也许@bozdoz 的答案就足够了,但如果您想排除第一年,您可能希望首先使用sortedsort、@987654329 对列表或元组中的键进行排序@、lambda 或这些的组合。或者,如果您想根据插入顺序而不是键的数值进行排序,请按照前面的建议使用 OrderedDict

标签: python django dictionary


【解决方案1】:

如果您不想在 Django 模板中显示 for 循环的第一次迭代,您可以通过检查 forloop.first 来省略它

 {% for year, durations in durationDict.items %}
      {% if not forloop.first %}
      <optgroup label={{ year }}>
      {% for duration in durations %}
           <option data-from-date="{{ duration.from_date }}" data-to-date="{{ duration.to_date }}" value={{ duration.duration_id }}>{{ duration.from_date }}
                                - {{ duration.to_date }}</option>
      {% endfor %}
      {% endif %}
 {% endfor %}

【讨论】:

    【解决方案2】:

    我最后做了如下:

    从我的字典中创建一个 OrderedDict,确保它按日期降序排序:

     duration_dict = OrderedDict(sorted(duration_dict.items(), key=lambda t: t[0], reverse=True))
    

    所以现在我可以确定第一个键也是最近的一年。 并按照@bozdoz 的建议,在没有第一年使用forloop.first 的情况下呈现所有键值对:

    {% for year, durations in duration_dict.items %}
                                {% if not forloop.first %}
                                <optgroup label={{ year }}>
                                {% endif %}
                               {% for duration in durations %}
                                  <option data-from-date="{{ duration.from_date }}" data-to-date="{{ duration.to_date }}" value={{ duration.duration_id }}>{{ duration.from_date }}
                                    - {{ duration.to_date }}</option>
                                {% endfor %}
                            {% endfor %}
    

    【讨论】:

      【解决方案3】:

      您可以使用filter 标签。例如:

      template_tags.py

      from django import template
      
      
      register = template.Library()
      
      @register.filter()
      def exclude_first(dict):
          first_key = list(dict)[0]
          del dict[first_key]
          return dict
      

      html

      {% load template_tags %}
      
      {% for year, durations in durationDict|exclude_first %}
      ...
      {% endfor %}
      

      这应该允许您遍历durationDict 除了中的所有项目的第一个项目。请记住,dicts 默认情况下不排序。如果您有一个每次都想删除的自定义键/值对,您只需将del dict[first_key] 替换为del dict['latest_year'](或将latest_year 替换为您要删除的键名)。

      【讨论】:

      • 请记住,dict 没有排序,因此您无法预测使用此方法将删除哪个键。
      • 很公平,我只是假设他使用ordered_dict() 或类似的东西来写这篇文章
      • 我还编辑了我的答案,以向 OP 展示如何删除 latest_year 键(或任何特定的键/值),假设最终这是他的目标。
      猜你喜欢
      • 2015-08-02
      • 1970-01-01
      • 2015-09-28
      • 2018-01-31
      • 2019-09-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多