【问题标题】:Is there a way to convert from string to integer while sorting in python using itemgetter or lambda?有没有办法在使用 itemgetter 或 lambda 在 python 中排序时从字符串转换为整数?
【发布时间】:2021-01-29 10:58:08
【问题描述】:

我有一本字典,其中所有的 id 都是字符串(id_categ、id_macrocateg、id_microcateg)。我不想迭代所有 dict 以将它们转换为整数并在对它们进行排序之后。我想知道是否有办法使用 itemgetter 或 lambda 在排序时将所有 id 转换为 int。

字典列表的示例可能是这样的(实际上,列表可以动态更改):

          l_dictt = [
            {'id_categ': '1', 'id_macrocateg': '1', 'id_microcateg': '1'},
            {'id_categ': '1', 'id_macrocateg': '1', 'id_microcateg': '111'},
            {'id_categ': '14', 'id_macrocateg': '1', 'id_microcateg': '35'},
            {'id_categ': '19', 'id_macrocateg': '1', 'id_microcateg': '9'},
            {'id_categ': '19', 'id_macrocateg': '1', 'id_microcateg': '19'},
            {'id_categ': '19', 'id_macrocateg': '1', 'id_microcateg': '26'},
            {'id_categ': '2', 'id_macrocateg': '50', 'id_microcateg': '554'},
            {'id_categ': '21', 'id_macrocateg': '1', 'id_microcateg': '4'},
            {'id_categ': '21', 'id_macrocateg': '1', 'id_microcateg': '16'},
            {'id_categ': '21', 'id_macrocateg': '1', 'id_microcateg': '17'},
            {'id_categ': '21', 'id_macrocateg': '1', 'id_microcateg': '20'},
            {'id_categ': '21', 'id_macrocateg': '1', 'id_microcateg': '21'},
            {'id_categ': '21', 'id_macrocateg': '1', 'id_microcateg': '24'},
            {'id_categ': '21', 'id_macrocateg': '1', 'id_microcateg': '31'},
            {'id_categ': '10', 'id_macrocateg': '2', 'id_microcateg': '11'},
            {'id_categ': '10', 'id_macrocateg': '2', 'id_microcateg': '12'},
            {'id_categ': '10', 'id_macrocateg': '2', 'id_microcateg': '13'},
            {'id_categ': '12', 'id_macrocateg': '2', 'id_microcateg': '10'},
            {'id_categ': '12', 'id_macrocateg': '2', 'id_microcateg': '27'},
            {'id_categ': '12', 'id_macrocateg': '2', 'id_microcateg': '28'},
            {'id_categ': '30', 'id_macrocateg': '6', 'id_microcateg': '112'},
            {'id_categ': '30', 'id_macrocateg': '6', 'id_microcateg': '112'}]

我想要的输出是:

            l_dictt = [
            {'id_categ': '1', 'id_macrocateg': '1', 'id_microcateg': '1'},
            {'id_categ': '1', 'id_macrocateg': '1', 'id_microcateg': '111'},
            {'id_categ': '14', 'id_macrocateg': '1', 'id_microcateg': '35'},
            {'id_categ': '19', 'id_macrocateg': '1', 'id_microcateg': '9'},
            {'id_categ': '19', 'id_macrocateg': '1', 'id_microcateg': '19'},
            {'id_categ': '19', 'id_macrocateg': '1', 'id_microcateg': '26'},
            {'id_categ': '21', 'id_macrocateg': '1', 'id_microcateg': '4'},
            {'id_categ': '21', 'id_macrocateg': '1', 'id_microcateg': '16'},
            {'id_categ': '21', 'id_macrocateg': '1', 'id_microcateg': '17'},
            {'id_categ': '21', 'id_macrocateg': '1', 'id_microcateg': '20'},
            {'id_categ': '21', 'id_macrocateg': '1', 'id_microcateg': '21'},
            {'id_categ': '21', 'id_macrocateg': '1', 'id_microcateg': '24'},
            {'id_categ': '21', 'id_macrocateg': '1', 'id_microcateg': '31'},
            {'id_categ': '10', 'id_macrocateg': '2', 'id_microcateg': '11'},
            {'id_categ': '10', 'id_macrocateg': '2', 'id_microcateg': '12'},
            {'id_categ': '10', 'id_macrocateg': '2', 'id_microcateg': '13'},
            {'id_categ': '12', 'id_macrocateg': '2', 'id_microcateg': '10'},
            {'id_categ': '12', 'id_macrocateg': '2', 'id_microcateg': '27'},
            {'id_categ': '12', 'id_macrocateg': '2', 'id_microcateg': '28'},
            {'id_categ': '30', 'id_macrocateg': '6', 'id_microcateg': '112'},
            {'id_categ': '30', 'id_macrocateg': '6', 'id_microcateg': '112'},
            {'id_categ': '2', 'id_macrocateg': '50', 'id_microcateg': '554'}]

如果这 3 个键是整数,我想首先按 id_macrocateg 排序,然后按 id_categ 和最后 id_microcateg,我可以这样做:

  for dictt in sorted(l_dictt, key=itemgetter('id_macrocateg', 'id_categ', 'id_microcateg'):
     print(dictt)

但由于是字符串,我不能这样做。

我试过了:

    from operator import itemgetter
    for dictt in sorted(l_dictt, key=lambda x: int(itemgetter("id_macrocateg, id_categ, id_microcateg")(x))):

           print(dictt)

还有这个:

  from operator import itemgetter
  for dictt in sorted(l_dictt, key=lambda x: int(itemgetter("id_macrocateg")(x)),int(itemgetter("id_categ")(x))),int(itemgetter(("id_microcateg")(x))):
     print(dictt)

【问题讨论】:

  • lambda x: tuple(map(int, x.values()))?
  • 如果 Python 支持函数组合,itemgetter 在这种情况下会好很多,例如sorted(l_dictt, key=int∘itemgetter("id_macrocateg"))。 IMO 运营商确实需要获得全部利益; key=compose(int, itemgetter("id_macrocateg")) 似乎还是太冗长了。
  • @SayanipDutta 假设(在这种情况下是安全的,但不是一般情况下)dict 中的每个值可以 转换为int,不管有没有必要。进行大量不必要的int 调用也可能代价高昂。
  • 但最重要的是,它在id_macrocateg之前排序id_categ
  • 或者对于多列,key=partial(map, int)∘itemgetter("id_macrocateg", "id_categ", "id_microcateg")

标签: python dictionary lambda


【解决方案1】:

您的第三次尝试只是缺少一些括号,以确保对int 的所有三个调用都是lambda 表达式主体的一部分。

from operator import itemgetter
for dictt in sorted(l_dictt, key=lambda x: (int(itemgetter("id_macrocateg")(x)),
                                            int(itemgetter("id_categ")(x))),
                                            int(itemgetter(("id_microcateg")(x))):
    print(dictt)

虽然itemgetter 真的只是在这里碍事。

for dictt in sorted(l_dictt, key=lambda x: (int(l_dictt["id_macrocateg"]),
                                            int(l_dictt["id_categ"]),
                                            int(l_dictt["id_microcateg"]):
    print(dictt)

您可以将mapitemgetter 一起使用,类似于您的第二次尝试:

from operator import itemgetter


# Splitting up for readability
getter = itemgetter("id_macrocateg", "id_categ", "id_microcateg")

for dictt in sorted(l_dictt, key=lambda x: tuple(map(int, getter(x))):
    print(dictt)

虽然带有键列表的生成器表达式可能更简单:

keys = ("id_macrocateg", "id_categ", "id_microcateg")

for dictt in sorted(l_dictt, key=lambda x: [int(x[k]) for k in keys]):

(仅因为没有元组理解而使用列表;列表和元组以相同的方式排序。)

【讨论】:

    【解决方案2】:

    更新问题后回答:

    现在,您希望列表按 id_macrocateg、id_categ 和 id_microcateg 排序,因此我们通过以下方式得到它:

    sorted(l_dictt, key=lambda x: x['id_macrocateg'].zfill(10)+x['id_categ'].zfill(10)+x['id_microcateg'].zfill(10))
    

    这里我假设最大位数可以是 10 位数 '9999999999',如果需要我们当然可以更新。

    结果

    {'id_categ': '1', 'id_macrocateg': '1', 'id_microcateg': '1'}
    {'id_categ': '1', 'id_macrocateg': '1', 'id_microcateg': '111'}
    {'id_categ': '14', 'id_macrocateg': '1', 'id_microcateg': '35'}
    {'id_categ': '19', 'id_macrocateg': '1', 'id_microcateg': '9'}
    {'id_categ': '19', 'id_macrocateg': '1', 'id_microcateg': '19'}
    {'id_categ': '19', 'id_macrocateg': '1', 'id_microcateg': '26'}
    {'id_categ': '21', 'id_macrocateg': '1', 'id_microcateg': '4'}
    {'id_categ': '21', 'id_macrocateg': '1', 'id_microcateg': '16'}
    {'id_categ': '21', 'id_macrocateg': '1', 'id_microcateg': '17'}
    {'id_categ': '21', 'id_macrocateg': '1', 'id_microcateg': '20'}
    {'id_categ': '21', 'id_macrocateg': '1', 'id_microcateg': '21'}
    {'id_categ': '21', 'id_macrocateg': '1', 'id_microcateg': '24'}
    {'id_categ': '21', 'id_macrocateg': '1', 'id_microcateg': '31'}
    {'id_categ': '10', 'id_macrocateg': '2', 'id_microcateg': '11'}
    {'id_categ': '10', 'id_macrocateg': '2', 'id_microcateg': '12'}
    {'id_categ': '10', 'id_macrocateg': '2', 'id_microcateg': '13'}
    {'id_categ': '12', 'id_macrocateg': '2', 'id_microcateg': '10'}
    {'id_categ': '12', 'id_macrocateg': '2', 'id_microcateg': '27'}
    {'id_categ': '12', 'id_macrocateg': '2', 'id_microcateg': '28'}
    {'id_categ': '30', 'id_macrocateg': '6', 'id_microcateg': '112'}
    {'id_categ': '30', 'id_macrocateg': '6', 'id_microcateg': '112'}
    {'id_categ': '2', 'id_macrocateg': '50', 'id_microcateg': '554'}
    

    更新问题前的初步回答:

    您可以按id_categ 的值对该字典进行排序,同时保持其值不变,如下所示:

    for dictt in sorted(l_dictt, key=lambda x: int(x['id_categ'])):
        print(dictt)
    

    结果

    {'id_categ': '1', 'id_macrocateg': '1', 'id_microcateg': '1'}
    {'id_categ': '1', 'id_macrocateg': '1', 'id_microcateg': '111'}
    {'id_categ': '2', 'id_macrocateg': '50', 'id_microcateg': '554'}
    {'id_categ': '10', 'id_macrocateg': '2', 'id_microcateg': '11'}
    {'id_categ': '10', 'id_macrocateg': '2', 'id_microcateg': '12'}
    {'id_categ': '10', 'id_macrocateg': '2', 'id_microcateg': '13'}
    {'id_categ': '12', 'id_macrocateg': '2', 'id_microcateg': '10'}
    {'id_categ': '12', 'id_macrocateg': '2', 'id_microcateg': '27'}
    {'id_categ': '12', 'id_macrocateg': '2', 'id_microcateg': '28'}
    {'id_categ': '14', 'id_macrocateg': '1', 'id_microcateg': '35'}
    {'id_categ': '19', 'id_macrocateg': '1', 'id_microcateg': '9'}
    {'id_categ': '19', 'id_macrocateg': '1', 'id_microcateg': '19'}
    {'id_categ': '19', 'id_macrocateg': '1', 'id_microcateg': '26'}
    {'id_categ': '21', 'id_macrocateg': '1', 'id_microcateg': '4'}
    {'id_categ': '21', 'id_macrocateg': '1', 'id_microcateg': '16'}
    {'id_categ': '21', 'id_macrocateg': '1', 'id_microcateg': '17'}
    {'id_categ': '21', 'id_macrocateg': '1', 'id_microcateg': '20'}
    {'id_categ': '21', 'id_macrocateg': '1', 'id_microcateg': '21'}
    {'id_categ': '21', 'id_macrocateg': '1', 'id_microcateg': '24'}
    {'id_categ': '21', 'id_macrocateg': '1', 'id_microcateg': '31'}
    {'id_categ': '30', 'id_macrocateg': '6', 'id_microcateg': '112'}
    {'id_categ': '30', 'id_macrocateg': '6', 'id_microcateg': '112'}
    

    【讨论】:

    • 谢谢,但问题是 id_macrocateg 不是有序的。我想先按 id_macrocateg 订购,然后按 id_categ 订购,最后按 id_microcateg 订购。我编辑了问题以更好地解释我需要什么。
    • 我发布答案后,您修改了您的问题。
    猜你喜欢
    • 2019-05-18
    • 1970-01-01
    • 1970-01-01
    • 2021-10-04
    • 2020-09-17
    • 1970-01-01
    • 2013-04-23
    • 1970-01-01
    • 2023-01-30
    相关资源
    最近更新 更多