I have a list of an arbitrary number of lists, for instance:
[[1,2,3], [3,4,5], [5,6,7], [7,8,9]]
Now I would like a list containing all elements that are present in more than one list:
[3,5,7]
How would I do that?
Thanks!
The same way as you'd do it by hand:
seen = set()
repeated = set()
for l in list_of_lists:
for i in set(l):
if i in seen:
repeated.add(i)
else:
seen.add(i)
By the way, here's the one liner (without counting the import) that some people were seeking (should be less efficient than the other approach)
from itertools import *
reduce(set.union, (starmap(set.intersection, combinations(map(set, ll), 2))))
l needs also to be 'setted', or you'll get false positives in [[1,1],[2,2]]for i in l: in for i in set(l):This only finds elements common to all lists (i.e, the intersection):
set.intersection(*[set(list) for list in list_of_lists])
[[1,2,3], [3,4,5], [5,6,7], [7,8,9]] i think its meant as a intersection of all lists ?Cleanest way would probably be to use reduce:
def findCommon(L):
def R(a, b, seen=set()):
a.update(b & seen)
seen.update(b)
return a
return reduce(R, map(set, L), set())
result = findCommon([[1,2,3], [3,4,5], [5,6,7], [7,8,9]])
Result is a set, but just do list(result) if you really need a list.
seen variable contains a "hidden" mutable state between calls... functional programming shouldn't rely on side effects (and it's a peril if they are not explicit, I bet that most of people wouldn't notice that seen is playing the role of a "static" variable instead of a regular argument)seen outside the parameter list of R and make it a local variable of findCommon.>>> sets = [[1,2,3], [3,4,5], [5,6,7], [7,8,9]]
>>> seen = set()
>>> duplicates = set()
>>>
>>> for subset in map(set, sets) :
... duplicates |= (subset & seen)
... seen |= subset
...
>>> print(duplicates)
set([3, 5, 7])
>>>
I tried for a one-line answer with map/reduce, but can't quite get it yet.
reference: http://docs.python.org/library/stdtypes.html#set
#!/usr/bin/python
ll = [[1,2,3], [3,4,5], [5,6,7], [7,8,9]]
ls = [set(l) for l in ll]
su = ls[0] #union
ssd = ls[0] #symmetric_difference
for s in ls[1:]:
su = su.union(s)
ssd = ssd.symmetric_difference(s)
result = su.difference(ssd)
print list(result)
=>
[3, 5, 7]
revise and adopt FP,
ll = [[1,2,3], [3,4,5], [5,6,7], [7,8,9]]
u = reduce(set.union, map(set, ll))
sd = reduce(set.symmetric_difference, map(set, ll))
print u - sd
=>
[3, 5, 7]
lst_of_lst=[[65L, 66L, 81L, 95L, 96L, 128L, 171L, 193L, 218L, 304L, 305L, 338L, 353L, 355L, 357L, 412L], [86L, 98L, 154L, 356L], [75L, 154L], [38L, 57L, 65L, 145L, 175L, 264L, 325L, 420L, 429L, 439L], [75L, 161L], [66L, 109L, 128L, 137L, 142L, 154L, 183L, 184L, 187L, 203L, 233L, 285L, 289L, 343L]] the result should be [128L, 65L, 66L, 154L, 75L],but your solution miss 154LYou can use a dictionary to get the count of each
from collections import defaultdict
init_list = [[1,2,3], [3,4,5], [5,6,7], [7,8,9]]
#defaultdict, every new key will have a int(0) as default value
d = defaultdict(int)
for values in init_list:
#Transform each list in a set to avoid false positives like [[1,1],[2,2]]
for v in set(values):
d[v] += 1
#Get only the ones that are more than once
final_list = [ value for value,number in d.items() if number > 1 ]
I am still learning but would like to share my answer.
num_list1 = ['3', '6', '5', '8', '33', '12', '7', '4', '72', '2', '42', '13']
num_list2 = ['3', '6', '13', '5', '7', '89', '12', '3', '33', '34', '1', '344', '42']
result = [int(num) for num in num_list1 if num in num_list2)
print(result)
This prints:
[3, 6, 5, 33, 12, 7, 42, 13]
Comparing all elements in both lists and creating a new list with similar elements. And turning them into integers.
flatten, sort, 1 for loop comparing numbers before and after