从列表元组中选择

时间:2015-10-17 20:20:43

标签: python python-2.7 python-3.x

我有一对名称对的元组列表,每对都有一个值,格式如下:

1.[('Carlo', 'Helen', 9), ('Carlo', 'Mary', 4), ('Jan', 'Rolly', 1), ('Renzi', 'Rolly', 3)] 
2.[('Sofy', 'Reem', 9), ('Sofy', 'David', 5),('Sofy', 'keem', 3) ('Roly', 'Tony', 4), ('Gianni', 'Tony', 2)]
3.[('Sofy', 'Reem', 9), ('Sofy', 'David', 5),('Sofy', 'keem', 3),('Roly', 'Reem', 5), ('Roly', 'David', 2),('Roly', 'keem', 3)]

我想要的是:对于列表中的每一行,如果两对或多对名称共享一个名称(第一个或第二个名称),我必须选择具有高值的对。因此,对于上面的示例,输出将是

  1-('Carlo', 'Helen', 9) 
    ('Renzi', 'Rolly', 3)
  2-('Sofy', 'Reem', 9)
    ('Roly', 'Tony', 4)

有人可以帮忙吗?

4 个答案:

答案 0 :(得分:1)

我还没有找到改进方法,但你可以对你的清单进行两次传递。在外循环中,每个项目被选择作为选择的候选者。在内部循环中,每个迭代以名称或姓氏匹配,并且当且仅当其得分高于当前候选时替换候选者以进行选择。在内部循环结束时,如果尚未插入候选列表,则将其插入选择列表。

def get_top_scorers(dataset):
    if dataset and all(isinstance(d, list) for d in dataset):
        return [get_top_scorers(d) for d in dataset]
    selected_list = []
    for candidate in dataset:
        chosen = candidate
        for next_candidate in dataset:
            if next_candidate == chosen:
                continue
            next_name, next_surname, next_score = next_candidate

            shares_name_with_selected = any(
                next_name == s[0] or next_surname == s[1]
                for s in selected_list
            )
            if shares_name_with_selected:
                continue

            name, surname, score = chosen
            if (name == next_name or surname == next_surname) and score < next_score:
                chosen = next_candidate

        shares_name_with_selected = any(
            chosen[0] == s[0] or chosen[1] == s[1]
            for s in selected_list
        )
        if chosen not in selected_list and not shares_name_with_selected:
            selected_list.append(chosen)
    return selected_list

答案 1 :(得分:0)

您需要两个功能。一个是迭代分组,另一个是查找最高值:

def find_highest_pair(tuple):
    highest_value = 0
    result = []
    for pair in tuple:
        if pair[2] > highest_value:
            highest_value = pair[2]
            result = pair
    return result

def grouping(tuple,n):
    stack = []
    result = []
    backup = []
    if tuple:
        check_pair = tuple.pop(0)
        backup = tuple
        if tuple:
            if check_pair[n] == tuple[0][n]:
                stack.append(tuple[0])
                tuple.pop(0)
        if not stack and len(tuple) > 0:
            return grouping(backup,n)
    stack.append(check_pair)
    result = find_highest_pair(stack)
    return result


tuple1 = [('Carlo', 'Helen', 9), ('Carlo', 'Mary', 4), ('Jan', 'Rolly', 1), ('Renzi', 'Rolly', 3)]
tuple2 = [('Sofy', 'Reem', 9), ('Sofy', 'David', 5), ('Sofy', 'keem', 3), ('Roly', 'Tony', 4), ('Gianni', 'Tony', 2)]

print "1:"
print grouping(tuple1,0)
print grouping(tuple1,1)
print "2:"
print grouping(tuple2,0)
print grouping(tuple2,1)

答案 2 :(得分:0)

这有效:

def fix_list(list_name):
    delete_list = []
    for i in range(len(list_name)):
        for j in range(len(list_name[i])):
            for k in range(1,len(list_name)):
                if i == k:
                    pass
                else:
                    if list_name[i][j] == list_name[k][j]:
                        if list_name[i][2] >= list_name[k][2]:
                            delete_list.append(list_name[k])
    list_name = [item for item in list_name if item not in delete_list]
    print list_name

    #Use return instead of print if you want to assign the new list to something

fix_list(list1)
fix_list(list2)

答案 3 :(得分:0)

 # this contains both lists
lt = [('Carlo', 'Helen', 9), ('Carlo', 'Mary', 4), ('Jan', 'Rolly', 1), ('Renzi', 'Rolly', 3),
                      ('Sofy', 'Reem', 9), ('Sofy', 'David', 5),('Sofy', 'keem', 3), ('Roly', 'Tony', 4), ('Gianni', 'Tony', 2)]

           def max_value_tuples(tuple_list):
            # find max value tuples in the list of tuple
            import itertools as it
            import operator as op
            groups = []

            # group by first element
            for k, g in it.groupby(tuple_list, key=op.itemgetter(0)):
                groups.append(list(g))
            # group by second element
            for k, g in it.groupby(tuple_list, key=op.itemgetter(1)):
                groups.append(list(g))

            final = []
            # leave out idividiual tuples
            for el in groups:
                if len(el) > 1:
                    final.append(el)

            result = []
            # sort and print with highest scrores
            for el in final:
                el = sorted(el, key=op.itemgetter(2))
                result.append(el[-1])

            return result

        print(max_value_tuples(lt))

        [('Carlo', 'Helen', 9), ('Sofy', 'Reem', 9), ('Renzi', 'Rolly', 3), ('Roly', 'Tony', 4)]

    with this and your astfile, you could do:

    all_lists = []
    for x in astfile:
        x_list = max_value_tuples(x)
        all_lists.append(x_list)