在不干扰列表之间的互补性的情况下,对Python的两个列表进行重新排序



我有两个Python列表:

numbers=[11, 12, 13, 10, 14, 2, 3] 
suits=['D', 'D', 'D', 'D', 'D', 'C', 'C']

这些列表按特定顺序排列,即11与D对应,2与C等对应。

我正试图编写一个函数,在不干扰赞美的情况下重新排列这些列表的顺序(即11使用D位)。函数有一个参数,用于确定列表的排序方式。第一个应该按数字顺序排列列表,从最高到最低,第二个应该按套装出现的次数排列,从列表中出现的次数最多到最少(所以在这个例子中有5个D和2个C,所以在这个情况下它们已经按正确的顺序排列了)。

这个函数的结构粘贴在下面,但我很难确定代码的实际排序部分。有人对如何做到这一点有什么建议吗?

def order_cards(order_by=suit):
    '''
    order_by has two arguments, either suit or number
    if suit: order by occurances of suit from largest to smallest
    if number: order by decreasing number
    '''
    if order_by='number':
        for i in range(len(numbers)): #Probably should iterate over the lists
            #code for ordering cards
            return ordered_cards
    elif order_by='suit':
        count=collections.Counter(suits) #This code count occurrences of suits
        #code to order by number of suits
        return ordered_cards
    else:
        return '{} is not 'suit' or 'number''.format(order_by)

我想,你想要这样的东西:

>>> numbers=[11, 12, 13, 10, 14, 2, 3]
>>> suits=['D', 'D', 'D', 'D', 'D', 'C', 'C']
>>> 
>>> t = zip(numbers,suits)
>>> t
[(11, 'D'), (12, 'D'), (13, 'D'), (10, 'D'), (14, 'D'), (2, 'C'), (3, 'C')]
>>> 
>>> 
>>> from operator import itemgetter
>>> sorted(t, key=itemgetter(0), reverse=True)#sort t by numbers from highest to lowest
[(14, 'D'), (13, 'D'), (12, 'D'), (11, 'D'), (10, 'D'), (3, 'C'), (2, 'C')]
>>> sorted(t, key=itemgetter(1)) #sort t by suits
[(2, 'C'), (3, 'C'), (11, 'D'), (12, 'D'), (13, 'D'), (10, 'D'), (14, 'D')]
>>> sorted(t, key=lambda s=itemgetter(0):suits.count(s[1]), reverse=True) #Sort by most occurence of cards
[(11, 'D'), (12, 'D'), (13, 'D'), (10, 'D'), (14, 'D'), (2, 'C'), (3, 'C')]

现在,在您的函数中应用以上内容:

from operator import itemgetter
def order_cards(order_by=suit):
    '''
    order_by has two arguments, either suit or number
    if suit: order by occurances of suit from largest to smallest
    if number: order by decreasing number
    '''
    t = zip(numbers,suits)    
    if order_by='number':
        lst = sorted(t, key=itemgetter(0), reverse=True)
        ordered_cards = [x[0] for x in lst]
        return ordered_cards
    elif order_by='suit':
        lst = sorted(t, key=lambda s=itemgetter(0):suits.count(s[1]), reverse=True) 
        ordered_cards = [x[1] for x in t]
        return ordered_cards
    else:
        return '{} is not 'suit' or 'number''.format(order_by)

将列表压缩在一起,生成一个包含元组的列表,元组将元素组合在一起。这个压缩列表可以很容易地排序。如果您确实需要将排序后的列表分开,请从排序后的组合列表中生成它们:

numbers = [11, 12, 13, 10, 14, 2, 3] 
suits = ['D', 'D', 'D', 'D', 'D', 'C', 'C']
combined = sorted(zip(numbers,suits))
numbers = [n for n,s in combined]
suits = [s for n,s in combined]

您需要将两个列表zip放在一起,并使用指定排序方式的lambda对生成的卡片进行排序。此代码示例按卡片的第一项进行排序,即数值。

numerical_sort = sorted(card for card in zip(numbers, suits), key = lambda card: card[0]) 

您可以使用zip将您的列表作为一个操作:

numbers=[11, 12, 13, 10, 14, 2, 3] 
suits=['D', 'D', 'D', 'D', 'D', 'C', 'C']
combined = zip(numbers, suits)  # [(11, 'D'), (12, 'D'), (13, 'D'), (10, 'D'), (14, 'D'), (2, 'C'), (3, 'C')]

第一个应该以数字顺序排列列表,从最高到最低

sorted_list = sorted(combined, key= lambda x: x[0])
numbers = [fst for fst, _ in sorted_list]  # [2, 3, 10, 11, 12, 13, 14]
suits = [snd for _, snd in sorted_list]  # ['C', 'C', 'D', 'D', 'D', 'D', 'D']

第二个应该按照诉讼发生的次数排序,从列表中发生次数最多到最少

from collections import Counter
count = Counter(suits)
sorted_list = sorted(combined, key= lambda x: count[x[1]], reverse=True)
numbers = [fst for fst, _ in sorted_list]  # [11, 12, 13, 10, 14, 2, 3]
suits = [snd for _, snd in sorted_list]  # ['D', 'D', 'D', 'D', 'D', 'C', 'C']

最新更新