【问题标题】:How to efficiently select entries by date in python?如何在python中按日期有效地选择条目?
【发布时间】:2014-09-18 16:32:25
【问题描述】:

我有电子邮件和日期。我可以使用 2 个嵌套的 for 循环来选择在同一日期发送的电子邮件,但我怎样才能“聪明地”做到这一点 - 高效?

# list of tuples - (email,date)

for entry in list_emails_dates:
    current_date = entry[1]
    for next_entry in list_emails_dates:
        if current_date = next_entry[1]
        list_one_date_emails.append(next_entry)

我知道它可以写成更短的代码,但我不知道itertools,或者可能使用mapxrange

【问题讨论】:

    标签: python map itertools xrange


    【解决方案1】:

    我会做一个(尝试使用 itertools 很好)

    itertools.groupby(list_of_tuples, lambda x: x[1])
    

    它为您提供按日期 (x[1]) 分组的电子邮件列表。请注意,执行此操作时,您必须针对同一组件对其进行排序 (sorted(list_of_tuples, lambda x: x[1]))。

    一件好事(除了告诉读者我们做一个分组)是它的工作很懒惰,如果列表有点长,它的性能主要由n log n 排序而不是n^2嵌套循环。

    【讨论】:

      【解决方案2】:

      您只需将与日期相关的所有电子邮件收集到同一个键中,即可将其转换为字典。

      为此,您需要使用集合中的defaultdict。为字典中的新键赋予默认值是一种简单的方法。

      这里我们传入函数list,这样字典中的每个新键都会得到一个列表作为默认值。

      emails = defaultdict(list)
      for email,email_date in list_of_tuples:
          emails[email].append(email_date)
      

      现在,您有emails['2013-14-07'],它将是该日期的电子邮件列表。

      如果我们不使用defaultdict,并像这样进行字典理解:

      emails = {x[1]:x[0] for x in list_of_tuples}
      

      每个日期都有一个条目,这将是该日期的最后封电子邮件,因为分配给相同的键将覆盖其值。字典是通过键查找值的最有效方式。如果您想通过一个值在一系列值中的位置来查找一个值(假设您知道它的位置),那么列表是很好的。

      如果由于某种原因你无法重构它,你可以使用这个模板方法,它会创建一个生成器:

      def find_by_date(haystack, needle):
          for email, email_date in haystack:
              if email_date == needle:
                  yield email
      

      您将如何使用它:

      >>> email_list = [('foo@bar.com','2014-07-01'), ('zoo@foo.com', '2014-07-01'), ('a@b.com', '2014-07-03')] 
      >>> all_emails = list(find_by_date(email_list, '2014-07-01'))
      >>> all_emails
      ['foo@bar.com', 'zoo@foo.com']
      

      或者,您可以这样做:

      >>> july_first = find_by_date(email_list, '2014-07-01')
      >>> next(july_first)
      'foo@bar.com'
      >>> next(july_first)
      'zoo@foo.com'
      

      【讨论】:

        猜你喜欢
        • 2011-03-08
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2010-09-09
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-11-01
        相关资源
        最近更新 更多