Python字典多个键,搜索功能

Python字典多个键,搜索功能,python,csv,dictionary,Python,Csv,Dictionary,我有以下名为results1111.CSV的示例CSV: Master #,Scrape,Date of Transaction 2C7E4B,6854585658,5/2/2007 2C7E4B,8283876134,5/8/2007 2C7E4B,4258586585,5/18/2007 C585ED,5554541212,5/18/2004 585868,5555551214,8/16/2012 我有以下代码打开CSV,然后将数据放入多个字典: with open('c:\\result

我有以下名为results1111.CSV的示例CSV:

Master #,Scrape,Date of Transaction
2C7E4B,6854585658,5/2/2007
2C7E4B,8283876134,5/8/2007
2C7E4B,4258586585,5/18/2007
C585ED,5554541212,5/18/2004
585868,5555551214,8/16/2012
我有以下代码打开CSV,然后将数据放入多个字典:

with open('c:\\results1111.csv', "r") as f:
    f.next()
    reader = csv.reader(f)
    result = {}
    for row in reader:
        key = row[0]
        result[key] = row[1:]
        values = row[1:]
        telnumber = row[1]
        transdate = row[2]
#print key
#print values
#print telnumber
#print transdate
#print result

        d = {}
        d.setdefault(key, []).append(values)
        print d
上述代码的输出为:

{'2C7E4B': [['6854585658', '5/2/2007']]}
{'2C7E4B': [['8283876134', '5/8/2007']]}
{'2C7E4B': [['4258586585', '5/18/2007']]}
{'C585ED': [['5554541212', '5/18/2004']]}
{'585868': [['5555551214', '8/16/2012']]}
我想在字典中搜索同一个键有多个电话号码的任何实例,例如上面输出的前三个条目。当这种情况发生时,我想删除最早日期的词典。然后我想将所有剩余的字典输出回CSV。输出应如下所示:

2C7E4B,8283876134,5/8/2007
2C7E4B,4258586585,5/18/2007
C585ED,5554541212,5/18/2004
585868,5555551214,8/16/2012

由于有数千个键(在真正的输入csv中),我不知道如何编写语句来实现这一点。非常感谢您的帮助。

您需要按日期对单个主控器的所有REOCRD进行排序,这比使用dict更容易完成。由于没有某种转换,月/日/年日期无法正确排序,因此我创建了一个datetime对象作为记录的第一项。现在,列表将按日期排序(如果两条记录的日期相同,则按电话号码排序),因此问题只是查找、排序和删除列表中的项目

import csv
import collections
import datetime as dt

open('temp.csv', 'w').write("""Master #,Scrape,Date of Transaction
2C7E4B,6854585658,5/2/2007
2C7E4B,8283876134,5/8/2007
2C7E4B,4258586585,5/18/2007
C585ED,5554541212,5/18/2004
585868,5555551214,8/16/2012
""")

with open('temp.csv') as f:
    f.next()
    reader = csv.reader(f)
    # map master to list of transactions
    result = collections.defaultdict(list)
    for row in reader:
        key = row[0]
        # make date sortable
        sortable_date = dt.datetime.strptime(row[2], '%m/%d/%Y')
        result[key].append([sortable_date, row[1], row[2]])

for value in result.values():
    # discard old records
    if len(value) > 1:
        value.sort()
        del value[0]
        # or to delete all but the last one
        # del value[:-1]

keys = result.keys()
keys.sort()

for key in keys:
    transactions = result[key]
    for transaction in transactions:
        print key, transaction[1], transaction[2]

这是一个你可能想要的想法。其基本思想是将日期聚合到同一个键下,最后清除最早的日期条目

#!/usr/bin/env python
import csv
import datetime

# this is used to parse the dates, you can change this if you change the format
DATE_FORMAT = "%m/%d/%Y"

# this is a dates comparator, to sort the dates when removing earliest date
def compare_dates(date1, date2):
    d1 = datetime.datetime.strptime(date1, DATE_FORMAT)
    d2 = datetime.datetime.strptime(date2, DATE_FORMAT)
    return int((d1 - d2).total_seconds())

with open('res.csv', "r") as f:
    f.next()
    reader = csv.reader(f)
    result = {}

    for row in reader:
        key = row[0]
        telnumber = row[1]
        transdate = row[2]
        # if it's a new key, we will need a new lst for the aggregation
        if not key in result:
            result[key] = []
        # thisis where we aggregate the all same-key entries
        result[key].append([telnumber, transdate,])

# this function takes in a key-value from the dictionary,
# and returns the earliest entry from the value (value being a list)
def clear_list(kv):
    k, v = kv
    if len(v) > 1:
        return {k: sorted(v, lambda x, y: compare_dates(x[1], y[1]))[1:]}
    return {k: v}

# simply clears all entries we've aggregated under each key.
print map(clear_list, result.items())

# ... now write back to csv

为什么
2C7E4B
在输出中出现两次?我知道一个普通的字典不能有重复的键。我写了最后三行代码,因为我需要有重复的密钥。2C7E48在输出上出现三次,因为这是一个实例,其中有两个具有不同值的重复键。也许有一种完全不同的方式来完成我想做的事情,但最终,如果主人是同一个人,并且有重复的电话号码,我需要去掉最早的条目。我不遵循。关键是什么?您的输入中有3个
2C7E4B
,输出中有2个。为什么只剩下两个而不是一个?或3?倒数第二个代码块是具有3的输出。最后一个代码块是我希望输出的显示方式。因此,基本上,您只想删除最早的字典?这就是为什么钥匙
2C7E4B
只删除了一个?非常感谢您的帮助!这也是一个很好的答案。谢谢