2016-12-20 5 views
0

То, что я пытаюсь сделать здесь, - это взять список наборов в качестве входных данных и вернуть набор элементов, которые встречаются во всех заданных наборах. Я получаю ошибку 'TypeError: list indices must be integers, not set'. Я не понимаю, почему это так, поскольку range(len(list_of_sets)) - это список целых чисел.TypeError: индексы списка должны быть целыми, а не Python

def intersection_of_sets(list_of_sets): 
    return reduce(lambda x, y: list_of_sets[x] &\ 
    list_of_sets[y], range(len(list_of_sets))) 

print(intersection_of_sets([{1, 2, 3}, {2, 3, 4}, {2, 5}, {1, 2, 5}])) 

Это ВЫВОД, что я буду за это set([2])

+0

http://stackoverflow.com/questions/22431647/typeerror-list-indices-must-be-integers-not-list-how-to-fix –

ответ

0

Проблема возникает на второй итерации/шаге reduce() операции после первой итерации/шаг был выработан комплекс:

list_of_sets[0] & list_of_sets[1] # returns a set 

Вы можете это наблюдать, если вы отлаживаете его и распечатываете значения x и y:

def intersection_of_sets(list_of_sets): 
    def merge_function(x, y): 
     print(x, y) 
     return list_of_sets[x] & list_of_sets[y] 

    return reduce(merge_function, range(len(list_of_sets))) 

Вы видели бы напечатал:

0 1 
{2, 3} 2 # < we've got a problem here 
... 
TypeError: list indices must be integers or slices, not set 

Что ты хотел сделать, это уменьшить сам list_of_sets:

def intersection_of_sets(list_of_sets): 
    return reduce(lambda x, y: x & y, list_of_sets) 

Демо:

In [1]: from functools import reduce 

In [2]: def intersection_of_sets(list_of_sets): 
    ...:  return reduce(lambda x, y: x & y, list_of_sets) 
    ...: 

In [3]: print(intersection_of_sets([{1, 2, 3}, {2, 3, 4}, {2, 5}, {1, 2, 5}])) 
set([2]) 
0

Поскольку вы обращаетесь целый набор, такой как {1,2,3}. Попробуйте вместо этого:

set([2][1]) 
0

перебирает все из них работает:

def intersection_of_sets(list_of_sets): 
    res = list_of_sets[0] 
    for s in list_of_sets[1:]: 
     res &= s 
    return res 

print(intersection_of_sets([{1, 2, 3}, {2, 3, 4}, {2, 5}, {1, 2, 5}])) 

Выход:

{2} 

Здесь &= оператор на месте, а это означает то же самое, как res = res & s.

0

Наборы имеют встроенную функцию, intersection

a = {1, 2, 3} 
b = {1, 2, 4} 
c = {0, 2, 5} 
a.intersection(b).intersection(c) 

возвращается: {2}

Просто создать рекурсивную функцию для сравнения двух первых и нажать на результат, пока вы не только длину одного на любой массив или результирующий набор.

def compareSets(arr): 
    if len(arr) == 1: return arr[0] 
    intersect = arr[0].intersection(arr[1]) 
    if len(arr) == 0: return {} 
    arr.append(intersect) 
    return compareSets(arr) 
Смежные вопросы