双重排序由字符串元组作为键和整数作为值组成的Dict,首先是元组中的第一个字符串,其次是值整数Python 3

时间:2017-01-30 06:26:28

标签: python python-3.x sorting dictionary tuples

我使用的是Python 3.5.2,我有dict包含"键"一个字符串元组,以及"值"计数中的整数。我想进行双重排序,其中第一个优先级是密钥中的第一个字符串,第二个优先级是整数值。请参阅下文以获得更深入的解释:

例如,我有一个Dict:

>>> print(unorderedDict.items())
dict_items([(('has', 'accomplished'), 1), (('new', 'french'), 1), (('pieces', 'machinery'), 1), (('in', 'those'), 1), (('east', 'on'), 1), (('sectarian', 'principles'), 1), ((',', 'are'), 10), (('all', 'countries'), 2)......])

它包含作为键的两个字符串的元组ex。 ('has', 'accomplished')以及一个整数ex的值。 1。防爆。所有在一起:([(('all', 'countries'), 2)])

这基本上包含文本中所有单词的独特组合,以元组形式作为键,以及单词组合在文本中作为整数值出现的次数。

我想要一种方法来排序unorderedDict,第一个按键元组中的第一个字符串,第二个按值排序。

这样做的目的是让我有一个单词列表,加上最有可能跟随它的单词,然后列表中的下一个单词加上下一个最可能出现在文本中的单词。

示例输出:

dict_items([(('all', 'the'), 10), (('all', 'of'), 7), (('big', 'drums), 12), (('big', 'dogs') 6)......])

注意它首先按元组中的第一个字符串(按字母顺序排序)排序,然后按值(从数字上最高到最低)排序。

为了执行这种类型的排序算法,我需要什么Python 3代码?

需要这种排序算法的主要原因是我可以随机选择元组中的第一个字符串之一,并获得更常见的元组中的第二个字符串(由Count中的Integer标识)。

例如,我可以随机选择所有'并且看到更有可能被“' ' of' of (' =' =' =' =#7;的数量。)

根据我自己的研究,我认为它可能与内置的dict排序方法和lambda有关,但这对我来说是新的领域,所以我不知道真的有线索。

1 个答案:

答案 0 :(得分:1)

基本上可以使用OrderedDict

来完成
from collections import OrderedDict
OrderedDict(sorted(unorderedDict.items(), key=lambda x: (x[0][0], x[1])))
#                                 first string of key----^^^^^^^  ^^^^---value

但我认为您应该考虑使用其他数据结构。例如,dict list的无序import bisect unorderedDict = dict([(('has', 'accomplished'), 1), (('has', 'done'), 5), (('new', 'french'), 1), (('has', 'failed'), 3), (('pieces', 'machinery'), 1), (('in', 'those'), 1), (('east', 'on'), 1), (('sectarian', 'principles'), 1), ((',', 'are'), 10), (('all', 'countries'), 2)]) result = {} for (key1, key2), counts in unorderedDict.items(): if key1 not in result: # add a new key result[key1] = [(counts, key2)] else: # We want the lists to be sorted so we can use bisection to do this quite efficient bisect.insort_left(result[key1], (counts, key2)) >>> print(result) {'sectarian': [(1, 'principles')], 'pieces': [(1, 'machinery')], ',': [(10, 'are')], 'all': [(2, 'countries')], 'has': [(1, 'accomplished'), (3, 'failed'), (5, 'done')], # sorted from low to high! 'new': [(1, 'french')], 'in': [(1, 'those')], 'east': [(1, 'on')]} 似乎是一个不错的选择,因为您只对第一个词后面最常见的词感兴趣:

from collections import Counter

result = {}

for (key1, key2), counts in unorderedDict.items():
    if key1 not in result:
        result[key1] = Counter()
    result[key1][key2] = counts

>>> result['has'].most_common()  # returns it sorted!!!
[('done', 5), ('failed', 3), ('accomplished', 1)]

>>> result['has'].most_common(1)
[('done', 5)]

>>> result['has']['failed']  # can be accessed like a dictionary too
3

外部词典没有订购,因为我怀疑它不是必须的(如果它应该是那时我不知道如何)。

替代方案可能是collections.Counter作为内部结构,因为它有一个很好的.most_common方法:

       var name : String? 

 override func awakeFromNib() {
           yourTextField.addTarget(self, action: #selector(self.doSomething(_:)), forControlEvents: UIControlEvents.EditingChanged)
       }

        func doSomething() {
           yourTextField.text
        }