i love crysis
i love crysis

Reputation: 341

Finding repeated values in multiple lists

I am trying to find if any of the sublists in list1 has a repeated value, so i need to be told if a number in list1[0] is the same number in list[1] (which 20 is repeated)

the numbers represent coords and the coords of each item in list1 cannot over lap, if they do then i have a module that reruns a make a new list1 untill no coords are the smae

please help

    list1 = [[7, 20], [20, 31, 32], [66, 67, 68],[7, 8, 9, 2],
             [83, 84, 20, 86, 87], [144, 145, 146, 147, 148, 149]]

    x=0
    while x != 169:
        if list1.count(x) > 0:
        print ("repeat found")
    else:
        print ("no repeat found")
    x+=1

Upvotes: 3

Views: 478

Answers (4)

Mike Müller
Mike Müller

Reputation: 85432

Solution for the updated question

def has_duplicates(iterable):
    """Searching for duplicates in sub iterables.

    This approach can be faster than whole-container solutions
    with flattening if duplicates in large iterables are found 
    early.
    """
    seen = set()
    for sub_list in iterable:
        for item in sub_list:
            if item in seen:
                return True
            seen.add(item)
    return False


>>> has_duplicates(list1)
True
>>> has_duplicates([[1, 2], [4, 5]])
False
>>> has_duplicates([[1, 2], [4, 5, 1]])
True

Lookup in a set is fast. Don't use a list for seen if you want it to be fast.

Solution for the original version of the question

If the length of the list is larger than the length of the set made form this list there must be repeated items because a set can only have unique elements:

>>> L = [[1, 1, 2], [1, 2, 3], [4, 4, 4]]
>>> [len(item) - len(set(item)) for item in L]
[1, 0, 2]

This is the key here

>>> {1, 2, 3, 1, 2, 1}
set([1, 2, 3])

EDIT

If your are not interested in the number of repeats for each sub list. This would be more efficient because its stops after the first number greater than 0:

>>> any(len(item) - len(set(item)) for item in L)
True

Thanks to @mata for pointing this out.

Upvotes: 2

squiguy
squiguy

Reputation: 33360

How about something like:

is_dup = sum(1 for l in list1 if len(set(l)) < len(l))
if is_dup > 0:
  print ("repeat found")
else:
  print ("no repeat found")

Another example using any:

any(len(set(l)) < len(l) for l in list1)

To check if only one item is repeated in all of the lists I would chain them and check. Credit to this answer for flattening a list of lists.

flattened = sum(list1, [])
if len(flattened) > len(set(flattened)):
  print ("dups")
else:
  print ("no dups")

I guess the proper way to flatten lists is to use itertools.chain which can be used as such:

flattened = list(itertools.chain(*list1))

This can replace the sum call I used above if that seems like a hack.

Upvotes: 3

perreal
perreal

Reputation: 97918

from collections import Counter
list1=[[7, 20], [20, 31, 32], [66, 67, 68],
        [7, 8, 9, 2], [83, 84, 20, 86, 87],
        [144,144, 145, 146, 147, 148, 149]]
for i,l in enumerate(list1):
    for r in [x for x,y in Counter(x for x in l).items() if y > 1]:
        print 'at list ', i, ' item ', r , ' repeats'

and this one gives globally repeated values:

expl=sorted([x for l in list1 for x in l])
print [x for x,y in zip(expl, expl[1:]) if x==y]

Upvotes: 1

mfaerevaag
mfaerevaag

Reputation: 730

For Python 2.7+, you should try a Counter:

import collections

list = [1, 2, 3, 2, 1]
count = collections.Counter(list)

Then count would be like:

Counter({1: 2, 2: 2, 3:1})

Read more

Upvotes: 0

Related Questions