在python中,我有一个类列表,其中包含一个名为category
的字符串字段。
让我们考虑以下示例:
mylist[0].category # = "furniture"
mylist[1].category # = "car"
mylist[2].category # = "fruit"
mylist[3].category # = "car"
mylist[4].category # = "furniture"
我的问题是:如何通过使用新类别的第一次出现进行分组来重新排序列表?
使用前面的示例,结果将是:
mylist[0].category # = "furniture"
mylist[1].category # = "furniture"
mylist[2].category # = "car"
mylist[3].category # = "car"
mylist[4].category # = "fruit"
答案 0 :(得分:2)
首先,按照与my_list
相同的顺序获取类别列表。然后,根据类别列表中每个项目类别的首次出现位置对my_list
进行排序。
categories = [item.category for item in my_list]
my_list.sort(key = lambda item: categories.index(item.category))
答案 1 :(得分:1)
# create a first-appearance index
order = {}
for ndx,item in enumerate(mylist):
if item.category not in order:
order[item.category] = ndx
# sort by that index
mylist.sort(key=lambda i: order[i])
答案 2 :(得分:0)
您可以通过遍历列表两次(无排序)来实现此目的:
from collections import defaultdict
# put all the items of the same category together
l = defaultdict( list )
for x in mylist:
l[ x.category ].append( x )
# expand in the order categories appear in the list
xs = [ ]
for x in mylist:
xs.extend( l[ x.category ] )
l.pop( x.category )
答案 3 :(得分:0)
也许是这样的?
#!/usr/local/cpython-3.3/bin/python
import pprint
CATEGORY_FIRST_SEEN = {}
def extract_order(list_of_class):
for index, element in enumerate(list_of_class):
if element.category not in CATEGORY_FIRST_SEEN:
CATEGORY_FIRST_SEEN[element.category] = index
#pprint.pprint(CATEGORY_FIRST_SEEN)
class Class_with_category:
def __init__(self, category):
self.category = category
def __cmp__(self, other):
if CATEGORY_FIRST_SEEN[self.category] < CATEGORY_FIRST_SEEN[other.category]:
return -1
elif CATEGORY_FIRST_SEEN[self.category] > CATEGORY_FIRST_SEEN[other.category]:
return 1
else:
return 0
def __lt__(self, other):
return self.__cmp__(other) < 0
def __str__(self):
return self.category
__repr__ = __str__
def main():
mylist = [ "furniture", "car", "fruit", "car", "furniture", ]
list_of_class = [ Class_with_category(element) for element in mylist ]
extract_order(list_of_class)
list_of_class.sort()
pprint.pprint(list_of_class)
main()
我已经测试过它可以在cpython 3.3上运行,但我相信它应该在2.x或3.x上运行。