【问题标题】:Grouping specific values from an array对数组中的特定值进行分组
【发布时间】:2015-10-10 16:57:26
【问题描述】:

假设我有一个这样的数组:

namesscore = ["Rory: 1", "Rory: 4", "Liam: 5", "Liam: 6", "Erin: 8", "Liam: 2",]

我想对该数组进行排序,使其如下所示:

namescore = ["Rory: 1, 4", "Liam: 5, 6, 2", "Erin: 8"]

我该怎么做?

【问题讨论】:

  • 您似乎想要一个使用名称作为键的字典并为它们分配一个可以使用附加的列表值。
  • 按照什么标准对最终数组进行排序?

标签: python arrays python-3.x


【解决方案1】:

我会迭代列表,并为每个项目将其拆分为名称和分数。然后我会创建一个字典(更准确地说:OrderedDict,以保留顺序)并累积每个名称的分数。迭代完成后,可以将其转换为所需格式的字符串列表:

from collections import OrderedDict

def group_scores(namesscore):
    mapped = OrderedDict()
    for elem in namesscore:
        name, score = elem.split(': ')
        if name not in mapped:
            mapped[name] = []
        mapped[name].append(score)

    return ['%s%s%s' % (key, ': ', ', '.join(value)) for \
              key, value in mapped.items()]

【讨论】:

  • 这会返回“AttributeError: 'OrderedDict' 对象没有属性 'iteritems'”
  • @Liwa 没有注意到python3 标签,这是一个过失。我编辑并用items() 替换了iteritems() 调用,它应该适用于python 2 和3。
【解决方案2】:
namesscore = ["Rory: 1", "Rory: 4", "Liam: 5", "Liam: 6", "Erin: 8", "Liam: 2"]
namesscore = [tuple(el.split()) for el in namesscore]
temp = dict((el[1], el[0]) for el in namesscore)

merge = {}
for key, value in temp.iteritems():
    if value not in merge:
        merge[value] = [key]
    else:
        merge[value].append(key)

print [' '.join((k, ' '.join(v))) for k, v in merge.iteritems()]

>>> ['Rory: 1 4', 'Liam: 2 5 6', 'Erin: 8']

【讨论】:

    【解决方案3】:
    from collections import defaultdict
    import operator
    
    namesscore = ["Rory: 1", "Rory: 4", "Liam: 5", "Liam: 6", "Erin: 8", "Liam: 2",]
    
    # Build a dictionary where the key is the name and the value is a list of scores
    scores = defaultdict(list)
    for ns in namesscore:
        name, score = ns.split(':')
        scores[name].append(score)
    
    # Sort each persons scores
    scores = {n: sorted(s) for n, s in scores.items()}   
    
    # Sort people by their scores returning a list of tuples
    scores = sorted(scores.items(), key=operator.itemgetter(1))   
    
    # Output the final strings
    scores = ['{}: {}'.format(n, ', '.join(s)) for n, s in scores]
    
    print scores
    
    > ['Rory:  1,  4', 'Liam:  2,  5,  6', 'Erin:  8']
    

    【讨论】:

    • 返回 "["L_K: {'4'}", "L_K: {'2'}", "L_K: {'0'}", "L_K: {'1'} ", "Rory_Follin: {'2'}", "Rory_Follin: {'2'}", "Rory_Follin: {'10'}"]" 在我的程序中运行时
    • @Liwa 你能发布你最初的namesscore 列表吗?看来您的价值观和结构可能与您的示例不同。
    【解决方案4】:
    namesscore = ["Rory: 1", "Rory: 4", "Liam: 5", "Liam: 6", "Erin: 8", "Liam: 2",]
    
    od = {}
    
    [ od.setdefault(a,[]).append(b) for a,b in map(lambda x : (x[0:x.find(':')],x[-1]), namesscore)]
    
    namesscore = ['  '.join((k,' '.join(sorted(v))))  for k, v in od.items()]
    
    print(namesscore)
    
    ['Erin  8', 'Liam  2 5 6', 'Rory  1 4']
    

    【讨论】:

      猜你喜欢
      • 2022-06-17
      • 2021-07-08
      • 2022-01-17
      • 1970-01-01
      • 2022-01-26
      • 1970-01-01
      • 2017-07-20
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多