Python 使用';itemgetter';根据字典元组中的最后一个、第一个名称排序?

Python 使用';itemgetter';根据字典元组中的最后一个、第一个名称排序?,python,sorting,python-3.x,dictionary,Python,Sorting,Python 3.x,Dictionary,我的程序将我的输入读入词典,将其格式化为标题格式,然后输出以供阅读。我们不使用类似于dictreader的东西。我想使用itemgetter按姓氏排序,然后按名字排序。正如您所看到的,我有一个使用lambda函数的工作版本的代码,因此我希望使用前面提到的itemgetter函数得到相同的结果 import sys from operator import itemgetter, attrgetter, methodcaller def data_2_dict(line): # con

我的程序将我的输入读入词典,将其格式化为标题格式,然后输出以供阅读。我们不使用类似于
dictreader
的东西。我想使用
itemgetter
按姓氏排序,然后按名字排序。正如您所看到的,我有一个使用
lambda
函数的工作版本的代码,因此我希望使用前面提到的
itemgetter
函数得到相同的结果

import sys
from operator import itemgetter, attrgetter, methodcaller


def data_2_dict(line):
    # constants
    NAME = 0
    ADDR = 1
    ADDR2 = 2
    CITY = 3
    STATE = 4
    ZIP = 5
    # split line and populate dictionary
    line = line.rstrip('\n')

    element = line.split(',')

    data_dict = {       
        'Name' : tuple(element[NAME].split(' ')),
        'Address' : element[ADDR],
        'Address2' : element[ADDR2],
        'City' : element[CITY],
        'State' : element[STATE],
        'Zip' : element[ZIP],
    }
    return format_data(data_dict)


def format_data(dict):
    for key, value in dict.iteritems():
        if key != 'Name' and key != 'State' and key != 'Zip':
            dict[key] = value.title()
        elif key == 'Name':
            dict[key] = (value[0].title(), value[1].title())

    return dict


def main():
    # gather in and out file, open objects
    infile = sys.argv[1]
    outfile = sys.argv[2]
    cust_list = []

    with open(infile, 'r') as myinfile:
        for line in myinfile.read().splitlines():
            data = data_2_dict(line)
            cust_list.append(data)

    # cust_list_sorted = sorted(cust_list, key=lambda key: (key['Name'][1], key['Name'][0]))
    cust_list_sorted = sorted(cust_list, key=itemgetter('Name'[1], 'Name'[0]))

    with open(outfile, 'w') as myoutfile:
        for line in cust_list_sorted:
            nameLine = 'Name: {0}, {1} ---\n'.format(line['Name'][1], line['Name'][0])
            myoutfile.write(nameLine)
            addrLine = '\tAddress: {0}, {1} {2}\n'.format(line['Address'],line['City'], line['State'])
            myoutfile.write(addrLine)
一行输入如下所示:

MICHELLE FULLER,265 MADEIRA AVE,,CHILLICOTHE,OH,00045
Name: Fuller, Michelle ---
    Address: 265 Madeira Ave, Chillicothe OH
cust_list_sorted = sorted(
    cust_list, key=lambda c, name=itemgetter('Name'): (name(c)[1], name(c)[0]))
一行输出应该如下所示:

MICHELLE FULLER,265 MADEIRA AVE,,CHILLICOTHE,OH,00045
Name: Fuller, Michelle ---
    Address: 265 Madeira Ave, Chillicothe OH
cust_list_sorted = sorted(
    cust_list, key=lambda c, name=itemgetter('Name'): (name(c)[1], name(c)[0]))

这在
itemgetter
中是不可能的,它返回一个从其操作数获取项的可调用项,因为您希望它做的是从其操作数的项“Name”中获取项0


如果必须使用
itemgetter
,只需将“FirstName”和“LastName”拆分并存储在字典中,然后使用
itemgetter(“LastName”、“FirstName”)
这在
itemgetter
中是不可能的,它返回一个可调用项,从其操作数中获取项,因为您希望它做的是从其操作数的项“Name”中提取项0


如果必须使用
itemgetter
,您可以将“FirstName”和“LastName”拆分并存储在字典中,然后使用
itemgetter(“LastName”、“FirstName”)
您可以这样做:

MICHELLE FULLER,265 MADEIRA AVE,,CHILLICOTHE,OH,00045
Name: Fuller, Michelle ---
    Address: 265 Madeira Ave, Chillicothe OH
cust_list_sorted = sorted(
    cust_list, key=lambda c, name=itemgetter('Name'): (name(c)[1], name(c)[0]))

这将为
'Name'
创建一个
itemgetter
,然后在
lambda
中使用它,该lambda以
(lastname,firstname)
的相反顺序返回元组

MICHELLE FULLER,265 MADEIRA AVE,,CHILLICOTHE,OH,00045
Name: Fuller, Michelle ---
    Address: 265 Madeira Ave, Chillicothe OH
cust_list_sorted = sorted(
    cust_list, key=lambda c, name=itemgetter('Name'): (name(c)[1], name(c)[0]))
这将为
'Name'
创建一个
itemgetter
,然后在
lambda
中使用它,该lambda以
(lastname,firstname)

的相反顺序返回元组(这主要是对的扩展,前面有一段关于Python中缺少函数组合的温和咆哮)

如果Python有一个内置的函数组合操作符(比如,
),您可以编写:

cust_list_sorted = sorted(cust_list, key=itemgetter(1, 0)∘itemgetter('Name'))
唉,Python没有(而且在可预见的将来也不会)这样的操作符,这意味着您可以编写

但这显然比

cust_list_sorted = sorted(cust_list, key=lambda obj: obj['Name'][::-1])
(比您已有的版本略短)

问题是
itemgetter
无法深入到嵌套数据结构中。如果像这样展平对象:

data_dict = {       
    'FirstName' : element[NAME].split(' ')[0],
    'LastName' : element[NAME].split(' ')[1],
    'Address' : element[ADDR],
    'Address2' : element[ADDR2],
    'City' : element[CITY],
    'State' : element[STATE],
    'Zip' : element[ZIP],
}
然后您可以将
itemgetter

cust_list_sorted = sorted(cust_list, key=itemgetter('LastName', 'FirstName'))
(这主要是对Python的扩展,开头是对Python中缺少函数组合的温和抨击。)

如果Python有一个内置的函数组合操作符(比如,
),您可以编写:

cust_list_sorted = sorted(cust_list, key=itemgetter(1, 0)∘itemgetter('Name'))
唉,Python没有(而且在可预见的将来也不会)这样的操作符,这意味着您可以编写

但这显然比

cust_list_sorted = sorted(cust_list, key=lambda obj: obj['Name'][::-1])
(比您已有的版本略短)

问题是
itemgetter
无法深入到嵌套数据结构中。如果像这样展平对象:

data_dict = {       
    'FirstName' : element[NAME].split(' ')[0],
    'LastName' : element[NAME].split(' ')[1],
    'Address' : element[ADDR],
    'Address2' : element[ADDR2],
    'City' : element[CITY],
    'State' : element[STATE],
    'Zip' : element[ZIP],
}
然后您可以将
itemgetter

cust_list_sorted = sorted(cust_list, key=itemgetter('LastName', 'FirstName'))

不过,我们自己实现
组合并不难,有些库提供了这样的元函数。组合运算符的美妙之处在于,它比
组合(itemgetter(1,0),itemgetter('Name'))之类的东西要简单得多,并且可以在足够低的级别上实现,比用户定义的可调用函数更高效。(
itemgetter('Name')
本身很容易用
lambda obj:obj['Name']
实现,但它是作为
lambda
表达式的有效替代品引入的。)不过,我们自己实现
组合并不难,有些库提供了这样的元函数。组合运算符的美妙之处在于,它比
组合(itemgetter(1,0),itemgetter('Name'))之类的东西要简单得多,并且可以在足够低的级别上实现,比用户定义的可调用函数更高效。(
itemgetter('Name')
本身很容易用
lambda obj:obj['Name']
实现,但它是作为
lambda
表达式的有效替代品引入的。)