Get the items not repeated in a list - python

Take two lists, second with same items than first plus some more:
a = [1,2,3]
b = [1,2,3,4,5]
I want to get a third one, containing only the new items (the ones not repeated):
c = [4,5]
The solution I have right now is:
>>> c = []
>>> for i in ab:
... if ab.count(i) == 1:
... c.append(i)
>>> c
[4, 5]
Is there any other way more pythonic than this?
Thanx folks!

at the very least use a list comprehension:
[x for x in a + b if (a + b).count(x) == 1]
otherwise use the set class:
list(set(a).symmetric_difference(set(b)))
there is also a more compact form:
list(set(a) ^ set(b))

If the order is not important and you can ignore repetitions within a and b, I would simply use sets:
>>> set(b) - set(a)
set([4, 5])
Sets are iterable, so most of the times you do not need to explicitly convert them back to list. If you have to, this does it:
>>> list(set(b) - set(a))
[4, 5]

Items in b that aren't in a, if you need to preserve order or duplicates in b:
>>> a = [1, 2, 3]
>>> b = [1, 2, 3, 4, 4, 5]
>>> a_set = set(a)
>>> [x for x in b if x not in a_set]
[4, 4, 5]
Items in b that aren't in a, not preserving order, and not preserving duplicates in b:
>>> list(set(b) - set(a))
[4, 5]

I'd say go for the set variant, where
set(b) ^ set(a) (set.symmetric_difference())
only applies if you can be certain that a is always a subset of b, but in that case has the advantage of being commutative, ie. you don't have to worry about calculating set(b) ^ set(a) or set(a) ^ set(b); or
set(b) - set(a) (set.difference())
which matches your description more closely, allows a to have extra elements not in b which will not be in the result set, but you have to mind the order (set(a) - set(b) will give you a different result).

Here are some different possibilities with the sets
>>> a = [1, 2, 3, 4, 5, 1, 2]
>>> b = [1, 2, 5, 6]
>>> print list(set(a)^set(b))
[3, 4, 6]
>>> print list(set(a)-set(b))
[3, 4]
>>> print list(set(b)-set(a))
[6]
>>> print list(set(a)-set(b))+list(set(b)-set(a))
[3, 4, 6]
>>>

Another solution using only lists:
a = [1, 2, 3]
b = [1, 2, 3, 4, 5]
c = [n for n in a + b if n not in a or n not in b]

a = [1, 2 ,3]
b = [1, 2, 3, 4, 5]
c=[]
for x in a:
if x not in b:
c.append(x)
print(c)

Related

python common list of values from two lists

a = [1, 2, 4]
b = [9, 2,2,2,3,3, 4,4]
c= set(a) & set(b)
print(c)
Result : {2, 4}
i need it like : {2,2,2,4,4}
Thank you
If you'd like the duplicates in the result to correspond to the duplicates in b.
(as in your example)
c= [i for i in b if i in a]
output:
[2, 2, 2, 4, 4]

Find common values in multiple lists [duplicate]

This question already has an answer here:
Get common values out of a list in python
(1 answer)
Closed 3 years ago.
So I have lists of numbers, and I would like to find numbers that exist in all the lists. I prefer not to use loop if possible.
Here is one example
a = [1, 2, 3, 4]
b = [2, 3, 4, 5, 6]
c = [3, 4, 5, 6, 10, 12]
df['A'] = [a, b, c]
The output is expected to be
[3, 4]
My problem here is, the number of lists is not given and not fixed. It can be about 20 lists with different lengths (e.g. [a, b, c, d, e, g, ..., l])
I have seen answers using set(a) & set(b) & set(c), but I am not sure how to apply this in my case.
You could use map along with set.intersection:
>>> a = [1, 2, 3, 4]
>>> b = [2, 3, 4, 5, 6]
>>> c = [3, 4, 5, 6, 10, 12]
>>> elements_in_all = list(set.intersection(*map(set, [a, b, c])))
>>> elements_in_all
[3, 4]
I'm not sure why you'd want to avoid loops, since that's .. really what you're asking for - looping over a list of lists and keeping the set of unique values.
l = [a, b, c]
s = None
for e in l:
if not s:
s = set(e)
else:
s &= set(e)
s => set([3, 4])
You can also create a functional version that doesn't explicitly use loops, and still support an arbitrary number of arguments:
reduce((lambda x,y: x & y), map(set, l))
First, convert every list in your containing list l to a set, then use reduce to apply the intersection for each element contained - the result is a single set with the elements common to all lists.
In [29]: a = [1, 2, 3, 4]
...: b = [2, 3, 4, 5, 6]
...: c = [3, 4, 5, 6, 10, 12]
In [31]: a, b, c = map(set, (a,b,c))
In [32]: a.intersection(b,c)
Out[32]: {3, 4}

Adding elements of lists in Python

How can I add up the elements of two lists in order to make a new list with the updated values. For example:
a = [1,2,3]
b = [3,4,5]
answer = [4,6,8]
I know this is a simple question, but I am new to this thing and cant find an answer anywhere else...
The zip() method would probably be the best way to add up columns, in that order.
a = [1, 3, 5] #your two starting lists
b = [2, 4, 6]
c = [] #the list you would print to
for x,y in zip(a, b): #zip takes 2 iterables; x and y are placeholders for them.
c.append(x + y) # adding on the the list
print c #final result
You may want to learn about list comprehensions, but for this task, it is not required.
>>> a = [1,2,3]
>>> b = [3,4,5]
>>> import operator
>>> map(operator.add, a, b)
[4, 6, 8]
For Python3, you need to use list with the result of map
>>> list(map(operator.add, a, b))
[4, 6, 8]
or just use the usual list comprehension
>>> [sum(x) for x in zip(a,b)]
[4, 6, 8]
>>> a = [1,2,3]
>>> b = [3,4,5]
>>> map(sum, zip(a, b))
[4, 6, 8]
You can use the itertools.izip_longest method to help with this:
def pairwise_sum(a, b):
for x, y in itertools.izip_longest(a, b, fillvalue=0):
yield x + y
You can then use it like this:
a = [1, 2, 3]
b = [3, 4, 5]
answer = list(pairwise_sum(a, b))

Add/sum two lists or tuples of uneven length

In Python, is there a good way to add/sum (or otherwise combine) two lists of uneven length?
e.g. given some lists:
a = [1,2,3]
b = [1,2,3,4]
produce list c:
c = [2,4,6,4]
where each element is the sum of a and b, taking a missing element as zero?
Yes, you can use itertools.zip_longest():
>>> from itertools import zip_longest
>>> a = [1, 2, 3]
>>> b = [1, 2, 3, 4]
>>> [x + y for x, y in zip_longest(a, b, fillvalue=0)]
[2, 4, 6, 4]
Here's what I landed up using:
[ (ax or 0) + (bx or 0) for (ax, bx) in map(None, a, b) ]
where n or 0 is used to coalesce None to zero, and map(None, a, b) is used as a null-expanding version of zip.
Problems? Better answers?
Another option:
In [1]: a = [1, 2, 3]
In [2]: b = [1, 2, 3, 4]
In [3]: [i+ii if i and ii else i or ii for (i,ii) in map(lambda x,y: (x,y),a,b)]
Out[3]: [2, 4, 6, 4]

How can I compare two lists in python and return matches [duplicate]

This question already has answers here:
How do I iterate through two lists in parallel?
(8 answers)
How to find list intersection?
(16 answers)
Closed 5 months ago.
I want to take two lists and find the values that appear in both.
a = [1, 2, 3, 4, 5]
b = [9, 8, 7, 6, 5]
returnMatches(a, b)
would return [5], for instance.
Not the most efficient one, but by far the most obvious way to do it is:
>>> a = [1, 2, 3, 4, 5]
>>> b = [9, 8, 7, 6, 5]
>>> set(a) & set(b)
{5}
if order is significant you can do it with list comprehensions like this:
>>> [i for i, j in zip(a, b) if i == j]
[5]
(only works for equal-sized lists, which order-significance implies).
Use set.intersection(), it's fast and readable.
>>> set(a).intersection(b)
set([5])
A quick performance test showing Lutz's solution is the best:
import time
def speed_test(func):
def wrapper(*args, **kwargs):
t1 = time.time()
for x in xrange(5000):
results = func(*args, **kwargs)
t2 = time.time()
print '%s took %0.3f ms' % (func.func_name, (t2-t1)*1000.0)
return results
return wrapper
#speed_test
def compare_bitwise(x, y):
set_x = frozenset(x)
set_y = frozenset(y)
return set_x & set_y
#speed_test
def compare_listcomp(x, y):
return [i for i, j in zip(x, y) if i == j]
#speed_test
def compare_intersect(x, y):
return frozenset(x).intersection(y)
# Comparing short lists
a = [1, 2, 3, 4, 5]
b = [9, 8, 7, 6, 5]
compare_bitwise(a, b)
compare_listcomp(a, b)
compare_intersect(a, b)
# Comparing longer lists
import random
a = random.sample(xrange(100000), 10000)
b = random.sample(xrange(100000), 10000)
compare_bitwise(a, b)
compare_listcomp(a, b)
compare_intersect(a, b)
These are the results on my machine:
# Short list:
compare_bitwise took 10.145 ms
compare_listcomp took 11.157 ms
compare_intersect took 7.461 ms
# Long list:
compare_bitwise took 11203.709 ms
compare_listcomp took 17361.736 ms
compare_intersect took 6833.768 ms
Obviously, any artificial performance test should be taken with a grain of salt, but since the set().intersection() answer is at least as fast as the other solutions, and also the most readable, it should be the standard solution for this common problem.
I prefer the set based answers, but here's one that works anyway
[x for x in a if x in b]
Quick way:
list(set(a).intersection(set(b)))
The easiest way to do that is to use sets:
>>> a = [1, 2, 3, 4, 5]
>>> b = [9, 8, 7, 6, 5]
>>> set(a) & set(b)
set([5])
>>> s = ['a','b','c']
>>> f = ['a','b','d','c']
>>> ss= set(s)
>>> fs =set(f)
>>> print ss.intersection(fs)
**set(['a', 'c', 'b'])**
>>> print ss.union(fs)
**set(['a', 'c', 'b', 'd'])**
>>> print ss.union(fs) - ss.intersection(fs)
**set(['d'])**
Also you can try this,by keeping common elements in a new list.
new_list = []
for element in a:
if element in b:
new_list.append(element)
Do you want duplicates? If not maybe you should use sets instead:
>>> set([1, 2, 3, 4, 5]).intersection(set([9, 8, 7, 6, 5]))
set([5])
another a bit more functional way to check list equality for list 1 (lst1) and list 2 (lst2) where objects have depth one and which keeps the order is:
all(i == j for i, j in zip(lst1, lst2))
Can use itertools.product too.
>>> common_elements=[]
>>> for i in list(itertools.product(a,b)):
... if i[0] == i[1]:
... common_elements.append(i[0])
You can use
def returnMatches(a,b):
return list(set(a) & set(b))
You can use:
a = [1, 3, 4, 5, 9, 6, 7, 8]
b = [1, 7, 0, 9]
same_values = set(a) & set(b)
print same_values
Output:
set([1, 7, 9])
One more way to find common values:
a = [1, 2, 3, 4, 5]
b = [9, 8, 7, 6, 5]
matches = [i for i in a if i in b]
If you want a boolean value:
>>> a = [1, 2, 3, 4, 5]
>>> b = [9, 8, 7, 6, 5]
>>> set(b) == set(a) & set(b) and set(a) == set(a) & set(b)
False
>>> a = [3,1,2]
>>> b = [1,2,3]
>>> set(b) == set(a) & set(b) and set(a) == set(a) & set(b)
True
a = [1, 2, 3, 4, 5]
b = [9, 8, 7, 6, 5]
lista =set(a)
listb =set(b)
print listb.intersection(lista)
returnMatches = set(['5']) #output
print " ".join(str(return) for return in returnMatches ) # remove the set()
5 #final output
Using __and__ attribute method also works.
>>> a = [1, 2, 3, 4, 5]
>>> b = [9, 8, 7, 6, 5]
>>> set(a).__and__(set(b))
set([5])
or simply
>>> set([1, 2, 3, 4, 5]).__and__(set([9, 8, 7, 6, 5]))
set([5])
>>>
The following solution works for any order of list items and also supports both lists to be different length.
import numpy as np
def getMatches(a, b):
matches = []
unique_a = np.unique(a)
unique_b = np.unique(b)
for a in unique_a:
for b in unique_b:
if a == b:
matches.append(a)
return matches
print(getMatches([1, 2, 3, 4, 5], [9, 8, 7, 6, 5, 9])) # displays [5]
print(getMatches([1, 2, 3], [3, 4, 5, 1])) # displays [1, 3]
you can | for set union and & for set intersection.
for example:
set1={1,2,3}
set2={3,4,5}
print(set1&set2)
output=3
set1={1,2,3}
set2={3,4,5}
print(set1|set2)
output=1,2,3,4,5
curly braces in the answer.
I just used the following and it worked for me:
group1 = [1, 2, 3, 4, 5]
group2 = [9, 8, 7, 6, 5]
for k in group1:
for v in group2:
if k == v:
print(k)
this would then print 5 in your case. Probably not great performance wise though.
This is for someone who might what to return a certain string or output,
here is the code, hope it helps:
lis =[]
#convert to list
a = list(data)
b = list(data)
def make_list():
c = "greater than"
d = "less_than"
e = "equal"
for first, first_te in zip(a, b):
if first < first_te:
lis.append(d)
elif first > first_te:
lis.append(c)
else:
lis.append(e)
return lis
make_list()

Categories

Resources