1

I have a list of lists, and I want to make a function that checks if each of the lists inside have exactly one item in common with all the other lists, if so return True. Couldn't make it work, is there a simple way to do it without using modules? I've tried something like this:

list_of_lists = [['d','b','s'],['e','b','f'],['s','f','l'],['b','l','t']]

new_list = []
for i in list_of_lists:
    for item in i:
        new_list.append(item)
if len(set(new_list)) == len(new_list)-len(list_of_lists):
    return True
wjandrea
  • 28,235
  • 9
  • 60
  • 81
Kimmo96
  • 11
  • 2
  • 3
    Can you write a function that tells you how many items there are in common between two lists? If you had that function, could you think of a way to solve the problem? – Karl Knechtel Nov 26 '20 at 17:00
  • Define lst and item. – DarknessPlusPlus Nov 26 '20 at 17:05
  • but here it's about a list of a not defind number of lists, could be any number. and the function receives only the list of lists. – Kimmo96 Nov 26 '20 at 17:07
  • Is each sublist guaranteed to have only one of each item? For instance, could a list contain `[d, b, s, s]`? If so, do you want to simply ignore that and treat it as `[d, b, s]`, or should that affect output? – CrazyChucky Nov 26 '20 at 17:09
  • 1
    each guranteed for one of each item and all are strings – Kimmo96 Nov 26 '20 at 17:16
  • As you will be working with indexes, your for loop will not work. You need to use for i in rage() to check an index. – DarknessPlusPlus Nov 26 '20 at 17:19
  • Doing for loops like this is an O(N^2) operation which is gonna be super slow unless this is a homework. The proper way to do it is to use a hashtable and check each element against that. It'll be more memory but O(N) run time – anishtain4 Nov 26 '20 at 17:23
  • Still can't figure it out.. if anyone can explain a proper way to do that – Kimmo96 Nov 27 '20 at 07:12

3 Answers3

1

if you want to intersect all the items in the sublist you can convert them to a set and find intersection check if its an empty set.

list_of_lists = [['d','b','s'],['e','b','f'],['s','f','l'],['b','l','t']]
common_items = set.intersection(*[set(_) for _ in list_of_lists])
if len(common_items) == 1:
    return True
return False
ATIF ADIB
  • 571
  • 5
  • 10
  • Shouldn't that be `if len(common_items) == 1`? They want to check if exactly one item is in common. – CrazyChucky Nov 26 '20 at 17:21
  • yes, i need to return True only if there is exactly one item in common in any sub list with all other sublists so this one doesn't work for that – Kimmo96 Nov 26 '20 at 17:42
  • updated the answer to return True, if only one item is common between all the sub lists – ATIF ADIB Nov 26 '20 at 17:50
  • 1
    You can simplify `if len(common_items) == 1: return True; else: return False` to `return len(common_items) == 1`. Also, don't use underscore `_` as the name here, since it's [often used to represent a throwaway name](https://stackoverflow.com/a/5893946/4518341); you could use say, `x` instead. – wjandrea Nov 26 '20 at 18:08
0

Using list comprehension:

def func(list_of_lists):
    return sum([all([item in lst for lst in list_of_lists[1:]]) for item in list_of_lists[0]]) == 1

Works if each is guaranteed for one of each item. Also if its not, returns True only if there is one match.

Hamza
  • 5,373
  • 3
  • 28
  • 43
0

use the Counter after joining a list and a compare list to determine occurrences. Ensure at least one item in the resulting list has a frequency of 2.

from collections import Counter

list_of_lists = [['d','b','s'],['e','b','f'],['s','f','l'],['b','l','t']]
for i in range(len(list_of_lists)):
    for j in range(i+1,len(list_of_lists)):
        result=(list_of_lists[i]+list_of_lists[j])
        counts=(Counter(result))
        matches={x for k,x in counts.items() if x==2}
        if len(matches)==0:
            print("missing a match")
Golden Lion
  • 3,840
  • 2
  • 26
  • 35