Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/351.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python根据每个列表的第一个值按自定义顺序排列列表_Python_Python 3.x_List_Sorting - Fatal编程技术网

Python根据每个列表的第一个值按自定义顺序排列列表

Python根据每个列表的第一个值按自定义顺序排列列表,python,python-3.x,list,sorting,Python,Python 3.x,List,Sorting,我想根据每个列表的第一个值按自定义顺序对列表列表进行排序。列表列表是pivot_表数据帧的我的列(cols=list(dfOverview.columns.values)),其中一些列本身就是一个列表 最简单的工作示例(我希望以b开头的列在c之前移动): 这会返回一个错误,尽管我尝试了很多次并在谷歌上搜索了很多次,但我找不到一种方法来让它工作。cols的预期结果: ['2016', '2017', '2018', ('a', '2016'), ('a', '2017'), ('a',

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

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

这会返回一个错误,尽管我尝试了很多次并在谷歌上搜索了很多次,但我找不到一种方法来让它工作。cols的预期结果:

['2016', '2017', '2018', 
 ('a', '2016'), 
 ('a', '2017'), 
 ('a', '2018'),  
 ('b', '2016'), 
 ('b', '2017'),
 ('c', '2016'), 
 ('c', '2017'), 
 ('c', '2018')]
为了澄清,我的问题的一些背景是:我对一个pandas数据框进行了数据透视,从而产生了一个新的数据框,其中的列可以由一系列值组成(以多列作为参数的透视表)。这使得订购变得困难,因此出现了上述问题

My dataframe是以下功能的结果:

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

问题源于您正在使用
。用于指定要比较的值的。您有一个异构列表。最后将比较不同类型的元素。我建议您看看
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种情况需要区分。
字符串
案例、
字符串元组
元组字符串
元组
案例

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

return
语句中使用的
cmp
函数只是通知术语之间的关系,
-1
a
0
a=b
1
a>b

请注意,比较是字典式的(字符串比较)。您可能希望将字符串大小写为整数,并比较它们

结果是:

['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')]

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

这将起作用。它将sort
key
设置为元组的第一个元素,或者将变量本身设置为其他元素

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')]

这样做有点老套,但你的方法也是老套的: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')]

谢谢!这是按字母顺序排序的,对吗?如何按自定义顺序对其进行排序(假设a之前是c)?您可以使用
reverse=True
参数,尽管我不确定这是否正是您想要的。最后,我想对数据帧的列进行重新排序,但由于我的dataframe是一个数据透视表,其中一些列名是一个列表而不是一个字符串。如果您需要其他订单,请随时更新问题&我可以更新答案。
>>> 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')]