【问题标题】:Iterating over Multiple Lists in Python When the Lists are Different Lengths当列表长度不同时迭代Python中的多个列表
【发布时间】:2016-07-13 02:29:05
【问题描述】:

我有这张数据表,我从 MySQL 数据库中提取并尝试匹配行,但我无法弄清楚最后一部分。我正在使用 Flask 将三个使用 'izip_longest' 的字典列表传递给 Jinja 模板,然后在 Jinja 模板中使用一个 for 循环来遍历每一行的变量。问题是我正在迭代的三个列表具有可变长度,并且并不总是相同的长度。

如下所示,我已经做到了这一点,但我需要在整行中匹配日期。在这种情况下,S-Date/07-11 应该在整行中为 07-11,或者在其他列中为空白。

S-Date | S-Place | G-Date | G-Place | F-Date | F-Place
------------------------------------------------------
 07-11     7       07-12     7        07-11      7
 07-12     7       07-13     7        
 07-13     7       07-14     7
 07-14     7

我觉得我快要弄明白了,但我一直盯着它看,却无法完全理解。

这是我从中提取数据的 SQL 表:

location | date | status
------------------------
 001      07-10    success
 002      07-10    success
 123      07-11    fail
 222      07-11    fail
 333      07-11    fail
 232      07-11    fail
 444      07-12    pending
 555      07-13    pending

这是获取每一天的失败次数的查询:

SELECT 'date', COUNT(`location`) as 'location' FROM mytable 
  WHERE YEARWEEK(`date`, 1) = YEARWEEK(CURDATE(), 1) 
   AND `status` LIKE '%fail%' GROUP BY DATE(`date`)

这是每天的成功次数:

SELECT `date`, COUNT(`location`) as 'location' FROM mytable 
   WHERE YEARWEEK(`date`, 1) = YEARWEEK(CURDATE(), 1) 
     AND `status` NOT LIKE '%fail%' GROUP BY DATE(`date`)

我需要将失败和成功与日期分组相匹配,这样我就可以生成堆叠条形图来显示单个日期/条形的每个数字。

【问题讨论】:

  • 您到底想达到什么目的?你有什么理由不能通过查询来做到这一点?
  • @e4c5 我最终试图生成一个堆叠条形图,其中一个段表示“成功”,一个段表示“失败”。 SQL 查询的问题是有时没有成功/失败,当使用“分组依据”时,我无法获得 0 值出现。我看到的与此问题相关的每个示例都涉及执行 JOIN,但我只使用一个表。
  • 为什么不发表让我们看看
  • @e4c5 我用一些附加信息编辑了我的原始帖子。
  • 谢谢,但还有人认为什么是 S-Date、G-Date 等?

标签: python mysql for-loop flask jinja2


【解决方案1】:

不太确定S-DateF-Date 的业务是什么,但我认为您想知道的是,您在每个独特的日期总共有多少成功和失败。

我有一个非常简单的 Python 解决方案:

from collections import defaultdict
from collections import Counter

data = defaultdict(list)

for row in database_table:
    data[row[1]].append(row[2])

results = {}

for date, attempts in data.iteritems():
   stats = Counter(attempts) 
   results[date] = {'total': len(attempts)}
   for stat, count in stats.most_common():
      results[date][stat] = count

现在 results 是一个字典,键是日期,值是另一个包含所有统计信息的字典。在您的模板中,您只需:

<table>
   <thead>
      <tr>
        <th>Date</th>
        <th>Total Places</th>
        <th>Success</th>
        <th>Failed</th>
        <th>Pending</th>
      </tr>
   </thead>
   <tbody>
     {% for date, stats in results.iteritems() %}
         <tr>
            <td>{{ date }}</td>
            <td>{{ stats['total'] }}</td>
            <td>{{ stats['success'] }}</td>
            <td>{{ stats['fail'] }}</td>
            <td>{{ stats['pending'] }}</td>
         </tr>
     {% endfor %}
   </tbody>
</table>

我遇到的一个问题是日期没有显示在 正确的顺序。他们从 07-14 到 07-11,而不是从 07-11 到 07-14。我知道 Python 字典没有排序,所以现在我需要 研究如何正确排序日期。

要对日期进行排序,首先需要将它们转换为日期时间对象;以便排序正常工作。

import datetime

# rest of the code here

fmt = '%m-%d'
results = [] # a list, so its sortable
for date, attempts in data.iteritems():
   stats = Counter(attempts) 
   record = {'total': len(attempts),
             'date': datetime.datetime.strptime(date, fmt)}
   for stat, count in stats.most_common():
      record[stat] = count

   results.append(record)

results = sorted(results, key=lamdba x: x['date'])

然后,只需调整您的模板:

{% for record in results %}
  <tr>
    <td>{{ record['date'] }}</td>
    <td>{{ record['total'] }}</td>
    <td>{{ record['success'] }}</td>
    <td>{{ record['fail'] }}</td>
    <td>{{ record['pending'] }}</td>
  </tr>
{% endfor %}

【讨论】:

  • 好的,我想我现在已经弄清楚了。在 Python 中执行此操作肯定比尝试按摩 MySQL 查询以获得我想要的要容易得多。非常感谢。
  • 我遇到的一个问题是日期没有按正确的顺序显示。他们从 07-14 到 07-11,而不是从 07-11 到 07-14。我知道 Python 字典没有排序,所以现在我需要研究如何正确排序日期。
猜你喜欢
  • 2018-02-02
  • 2017-10-15
  • 2013-10-07
  • 2022-06-11
  • 2022-01-23
  • 2021-01-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多