Python基于每个lis的第一个值按自定义顺序排列的列表列表

2024-09-29 04:31:03 发布

您现在位置:Python中文网/ 问答频道 /正文

我想根据每个列表的第一个值按自定义顺序对列表进行排序。列表列表是pivot表dataframe(cols = list(dfOverview.columns.values))的我的列,其中一些列本身就是一个列表。你知道吗

最简单的工作示例(我希望以b开头的列移到c之前):

cols = ['2016', '2017', '2018', 
        ('a', '2016'), 
        ('a', '2017'), 
        ('a', '2018'), 
        ('c', '2016'), 
        ('c', '2017'), 
        ('c', '2018'), 
        ('b', '2016'), 
        ('b', '2017')]

sortOrder = {'2016': 0, '2017': 1, '2018': 2, 'a': 3, 'b': 4, 'c': 5}

cols.sort(key=lambda val: sortOrder[val[0]])

这返回了一个错误,即使我尝试了很多,google搜索了很多,我也找不到一个方法让它工作。cols的预期结果:

['2016', '2017', '2018', 
 ('a', '2016'), 
 ('a', '2017'), 
 ('a', '2018'),  
 ('b', '2016'), 
 ('b', '2017'),
 ('c', '2016'), 
 ('c', '2017'), 
 ('c', '2018')]

为了澄清我的问题的一些背景:我对一个pandas数据框进行了透视,得到了一个新的数据框,其中的列可以由一系列值组成(以多列作为参数的透视表)。这使得订购变得困难,因此出现了上述问题。你知道吗

我的数据帧是以下函数的结果:

dfPivot = df.pivot_table(index=['col1', 'col2'], 
                         columns=['year','category'], 
                         values='price')

Tags: columns数据示例dataframe列表排序顺序val
3条回答

这会有用的。它将sortkey设置为元组的第一个元素,否则设置为变量本身。你知道吗

cols = ['2016', '2017', '2018', 
        ('a', '2016'), 
        ('a', '2017'), 
        ('a', '2018'), 
        ('c', '2016'), 
        ('c', '2017'), 
        ('c', '2018'), 
        ('b', '2016'), 
        ('b', '2017')]

sorted(cols, key=lambda k: k[0] if isinstance(k, tuple) else k)

# ['2016',
#  '2017',
#  '2018',
#  ('a', '2016'),
#  ('a', '2017'),
#  ('a', '2018'),
#  ('b', '2016'),
#  ('b', '2017'),
#  ('c', '2016'),
#  ('c', '2017'),
#  ('c', '2018')]

这个问题源于您正在使用key。用于指定要比较的值的。你有一个异类名单。最后将比较不同类型的元素。我建议您看看cpm参数,它是一个比较两个元素的函数。这样,您可以更精确地使用排序规则。你知道吗

如果我对你的问题理解正确,你很可能会想要这样:

def compare(a, b):
    if isinstance(a, str) and isinstance(b, str):
        return cmp(a, b)
    elif isinstance(a, str) and isinstance(b, tuple):
        return cmp(a, b[1])
    elif isinstance(b, str) and isinstance(a, tuple):
        return cmp(a[1], b)
    elif isinstance(a, tuple) and isinstance(b, tuple):
        return cmp(a[1], b[1])
    else:
        print "Impossible"

    return 0

cols.sort(cmp=compare)
print cols

在查看列表输入时,有4种情况需要区分。string string病例、string tupletuple stringtuple tuple病例。你知道吗

我们对每种情况进行说明,并为每种情况编写比较规则。你知道吗

return语句中使用的cmp函数只是通知术语之间的关系,-1表示a < b0表示a = b1表示a > b。你知道吗

请注意,比较是lexicographic(字符串比较)。您可能需要将字符串大小写为整数并比较它们。你知道吗

结果是:

['2016', ('a', '2016'), ('c', '2016'), ('b', '2016'), '2017', ('a', '2017'), ('c', '2017'), ('b', '2017'), '2018', ('a', '2018'), ('c', '2018')]

如果将访问元组的第二个元素(本例中的年份)替换为访问第一个元素,则会得到以下结果:

['2016', '2017', '2018', ('a', '2016'), ('a', '2017'), ('a', '2018'), ('b', '2016'), ('b', '2017'), ('c', '2016'), ('c', '2017'), ('c', '2018')]

您可以添加一个标志来决定比较应该使用元组的哪个项。你知道吗

这样做有点老套,但你的方法也很老套:D

>>> sorted(cols, key=lambda val: sortOrder[val[0]] if type(val) == tuple else sortOrder[val])

['2016', '2017', '2018', ('a', '2016'), ('a', '2017'), ('a', '2018'), ('b', '2016'), ('b', '2017'), ('c', '2016'), ('c', '2017'), ('c', '2018')]

相关问题 更多 >