9

I am trying to find an easy way to do this:

list1 = ['little','blue','widget']
list2 = ['there','is','a','little','blue','cup','on','the','table']

I want to get common elements of the two lists, with list1's order untouched, so this result is expected.

list3 = ['little','blue']

I am using

list3 = list(set(list1)&set(list2))

however, this only returns list3 = ['blue', 'little'], obviously, set() just ignore the order.

user202729
  • 3,358
  • 3
  • 25
  • 36
michelle26
  • 95
  • 1
  • 2
  • 5

4 Answers4

11

You were almost there, just sort list3 according to list1

list1 = ['little','blue','widget']
list2 = ['there','is','a','little','blue','cup','on','the','table']

list3 = set(list1)&set(list2) # we don't need to list3 to actually be a list

list4 = sorted(list3, key = lambda k : list1.index(k))

Result:

>>> list4
['little', 'blue']
Akavall
  • 82,592
  • 51
  • 207
  • 251
  • This is not as efficient as the [other solution](https://stackoverflow.com/a/18264481/5267751), as it have to compute `list1.index` (takes linear time) for each element in `list3`. – user202729 Aug 15 '21 at 03:30
6

Using list comprehension:

>>> list1 = ['little','blue','widget']
>>> list2 = ['there','is','a','little','blue','cup','on','the','table']
>>> s = set(list2)
>>> list3 = [x for x in list1 if x in s]
>>> list3
['little', 'blue']
falsetru
  • 357,413
  • 63
  • 732
  • 636
  • Are you converting list2 to a set first because sets are faster to search, or is there another reason? – Brionius Aug 16 '13 at 01:38
  • 2
    @Brionius, Converting `list2` for the search speed. No other reason. – falsetru Aug 16 '13 at 01:41
  • What if `list1 = ['little','blue','widget', 'little']`? Then your method would produce `['little', 'blue', 'little']`. – Akavall Aug 17 '13 at 02:09
  • 1
    @Akavall, If you want `['little', 'blue']`, use `[x for x in OrderedDict.fromkeys(list1) if x in s]` instead. – falsetru Aug 17 '13 at 03:01
0

Here's an implementation using filter:

list1 = ['little','blue','widget']
list2 = ['there','is','a','little','blue','cup','on','the','table']
set2 = set(list2)
f = lambda x:x in set2

list3 = filter(f, list1)
Brionius
  • 13,858
  • 3
  • 38
  • 49
0

This does what your asking for using python 2.7, not particularly elegant but it does answer your question.

list1 = ['little','blue','widget']
list2 = ['there','is','a','little','blue','cup','on','the','table']
list3 = []
for l1 in list1:
    for l2 in list2:
        if l2 == l1:
            list3.append(l2)

print list3  # ['little', 'blue']