I have the following lists
a=[1,2,3]
b=[4,5,6]
c=[a,b]
i need to combine both list a and b.
result should be like [1,2,3,4,5,6]
i tried with list comprehension
[x for x in i for i in c]
output
[3, 3, 4, 4, 5, 5]
How can i get the result as [1,2,3,4,5,6] using list comprehension.
You can just do:
a + b
If you must use list comprehension:
In [10]: a = [1, 2, 3]
In [11]: b = [4, 5, 6]
In [12]: c = [a, b]
In [13]: [j for i in c for j in i]
Out[13]: [1, 2, 3, 4, 5, 6]
Use itertools.chain.
import itertools
a=[1,2,3]
b=[4,5,6]
c = list(itertools.chain(a, b))
You are concatenating, use + to do so:
c = a + b
If you are concatenating an arbitrary number of lists, use itertools.chain.from_iterable():
from itertools import chain
list_of_lists = [a, b]
c = list(chain.from_iterable(list_of_lists))
Note that if all you need to do is iterate over the concatenation result, you can leave of the list() call altogether.
Do not use sum() for this; that leads to quadratic behaviour as intermediate results are built for every element summed, which takes a full loop.
You can do it with + operation
a = [1, 2, 3]
b = [3, 4, 5]
c = a + b # Equal [1, 2, 3, 3, 4, 5]
Here are 3 different ways you can do it:
>>> a=[1,2,3]
>>> b=[4,5,6]
>>> c=a+b
>>> c
[1, 2, 3, 4, 5, 6]
>>> c=[item for l in [a, b] for item in l]
>>> c
[1, 2, 3, 4, 5, 6]
>>> import itertools
>>> list(itertools.chain(*[a, b]))
[1, 2, 3, 4, 5, 6]
Related
Is it possible somehow to preform logical functions on arrays like eg.
a= [1,2,3,4,5,6]
b= [1,3,5,7]
c= a and b
resulting in c=[1,3,5]
so only the values that are present in both the arrays.
The same with or eg:
d = a OR b
resulting in b=[1,2,3,4,5,6,7]
Is this possible somehow in python or are there short functions for this?
Thanks for your response
Lists do not support logical operations , but you can do it in sets:
a= [1,2,3,4,5,6]
b= [1,3,5,7]
c = list(set(a) | set(b))
d = list(set(a) & set(b))
print(c)
# OUTPUT: [1, 2, 3, 4, 5, 6, 7]
print(d)
# OUTPUT: [1, 3, 5]
You probably should use python set if your collections contain unique values. They are actually mathematical sets: https://en.wikipedia.org/wiki/Set_(mathematics) and support general operation for sets such as intersection and union
>>> a = {1, 2, 3, 4, 5, 6}
>>> b = {1, 3, 5, 7}
>>> c = a.intersection(b)
>>> c
{1, 3, 5}
Here is your snippet:
def and_array(a, b):
return [a[i] for i in range(min(len(a), len(b))) if a[i] in b or b[i] in a]
def or_array(a, b):
return a + [element for element in b if not element in a]
a= [1,2,3,4,5,6]
b= [1,3,5,7]
c = and_array(a, b)
d = or_array(a, b)
print(c)
print(d)
Result:
[1, 2, 3]
[1, 2, 3, 4, 5, 6, 7]
It is not that fast, avoid this for very large lists and use numpy or build-in functions!
Given multiple lists like the ones shown:
a = [1, 2, 3]
b = [5, 6, 7, 8]
c = [9, 0, 1]
d = [2, 3, 4, 5, 6, 7]
...
I want to be able to combine them to take as many elements from the first list as I can before starting to take elements from the second list, so the result would be:
result = [1, 2, 3, 8, 6, 7]
Is there a particularly nice way to write this? I can't think of a really simple one without a for loop. Maybe a list comprehension with a clever zip.
Simple slicing and concatenation:
a + b[len(a):]
Or with more lists:
res = []
for lst in (a, b, c, d):
res += lst[len(res):]
# [1, 2, 3, 8, 6, 7]
With itertools.zip_longest() for Python 3, works on any number of input lists:
>>> from itertools import zip_longest
>>> [next(x for x in t if x is not None) for t in zip_longest(a,b,c,d)]
[1, 2, 3, 8, 6, 7]
The default fill value is None so take the first none None element in each tuple created with the zip_longest call (you can change the defaults and criteria if None is a valid data value)
With functools.reduce:
from functools import reduce
print(list(reduce(lambda a, b: a + b[len(a):], [a, b, c, d])))
This outputs:
[1, 2, 3, 8, 6, 7]
So I have 2 lists, say list a and list b where
a = [9, 8, 7, 6]
b = [1, 2, 3, 4]
How would I go about subtracting the contents of b from a?
You can use the map function and it's feature to support more than one iterable (the following assumes Python2):
>>> a = [9, 8, 7, 6]
>>> b = [1, 2, 3, 4]
>>> map(lambda x,y: x-y, a, b)
[8, 6, 4, 2]
map applies the first argument (which has to be a function) on all elements of the following arguments. For example:
>>> from math import sqrt
>>> map(sqrt, [1,2,9])
[1.0, 1.4142135623730951, 3.0]
If you use more than two arguments, the function in the first parameter must take more parameters, because it is called with elements from each list:
>>> from math import pow
>>> map(pow, [2,3,4], [2,3,4])
[4.0, 27.0, 256.0]
The result is 2^2, 3^3 and 4^4.
The lambda in my example is just a shorter way to define the subtraction function, the following code would do the same:
def sub(x,y):
return x-y
map(sub, a, b)
You can zip the two lists and subtract the subelements to create a new list:
zip(b,a) -> [(1, 9), (2, 8), (3, 7), (4, 6)]
a = [9, 8, 7, 6]
b = [1, 2, 3, 4]
print([y-x for x,y in zip(b,a)])
[8, 6, 4, 2]
If you want to change a itself use enumerate subtracting elements at common indexes:
for ind,ele in enumerate(a):
a[ind] -= b[ind]
print(a)
[8, 6, 4, 2]
Or using numpy:
import numpy as np
a = np.array([9, 8, 7, 6])
b = np.array([1, 2, 3, 4])
print(a - b)
[8 6 4 2]
a=[1,2,3,4,5]
b=[9,8,7,6,4]
t=0
h=[]
lenA=len(a)
while lenA != t:
x=a[t]-b[t]
t=t+1
h.append(x)
The dictionary's methods .viewvalues() and .viewkeys() allow to create the list variables that will be linked and dynamically updated on every dictionary modification such as:
diction={'one':1,'two':2,'three':3}
dict_values=dictVar.viewvalues()
dict_keys=dictVar.viewkeys()
I wonder if a similar functionality could be achieved with lists. So if there are two "source" list variables and a third list is a result of sums of twos:
a=[1,2,3]
b=[4,5,6]
sum=a+b
Now what i want is a list variable sum to get updated if/when list variable a or list variable b is modified. How to achieve that?
I'd define a function to do it and then call that whenever you need the list.
a=[1,2,3]
b=[4,5,6]
def sum(a, b):
return a + b
Then, in an interpreter:
>>> sum(a, b)
[1, 2, 3, 4, 5, 6]
>>> a.append(5)
>>> sum(a, b)
[1, 2, 3, 5, 4, 5, 6]
If it's not necessary that it be a flat list, you can easily do what you'd want.
>>> a = [1, 2, 3]
>>> b = [4, 5, 6]
>>> sum = [a, b]
>>> print(sum)
[[1, 2, 3], [4, 5, 6]]
>>> a.append(8)
>>> print(sum)
[[1, 2, 3, 8], [4, 5, 6]]
That said, I'd recommend against defining a variable named sum as it's a built-in Python function.
You could do it the other way around, using numpy arrays.
>>> import numpy as np
>>> ab = np.array([1,2,3,4,5,6])
>>> a = ab[:3]
>>> b = ab[3:]
>>> a, b
(array([1, 2, 3]), array([4, 5, 6]))
>>> a[1] = 9
>>> ab
array([1, 9, 3, 4, 5, 6])
>>> ab[0] = 7
>>> a
array([7, 9, 3])
Here, a and b are "views" on the array ab, and modifying one will also modify the other.
Starting with a and b, just create a numpy array from a+b and redefine a and b accordingly:
>>> a, b = [1,2,3], [4,5,6]
>>> ab = np.array(a+b)
>>> a, b = ab[:3], ab[3:]
You will have to right a custom data structure to do this. Here is something in the right direction...
class LinkedArrays(object):
def __init__(self, sourceArray1, sourceArray2, combineFunction):
self.sa1, self.sa2 = sourceArray1, sourceArray2
self.__combineFunction = combineFunction
self.__update()
def updateSourceArray1(self, index, value):
self.sa1[index] = value
self.__update()
def updateSourceArray2(self, index, value):
self.sa2[index] = value
self.__update()
def __update(self):
self.combinedArray = [self.__combineFunction(self.sa1[i], self.sa2[i]) for i in range(len(self.sa1))]
def __getitem__(self, item):
return self.combinedArray[item]
summedArrays = LinkedArrays([1, 2, 3], [4, 5, 6], lambda x, y: x+y)
print summedArrays[0] # print 5
summedArrays.updateSourceArray1(0, 6)
print summedArrays[0] # print 10
For two lists a and b, how can I get the indices of values that appear in both? For example,
a = [1, 2, 3, 4, 5]
b = [9, 7, 6, 5, 1, 0]
return_indices_of_a(a, b)
would return [0,4], with (a[0],a[4]) = (1,5).
The best way to do this would be to make b a set since you are only checking for membership inside it.
>>> a = [1, 2, 3, 4, 5]
>>> b = set([9, 7, 6, 5, 1, 0])
>>> [i for i, item in enumerate(a) if item in b]
[0, 4]
def return_indices_of_a(a, b):
b_set = set(b)
return [i for i, v in enumerate(a) if v in b_set]
For larger lists this may be of help:
for item in a:
index.append(bisect.bisect(b,item))
idx = np.unique(index).tolist()
Be sure to import numpy.
you can do it like this,with no need to set :
a = [1, 2, 3, 4, 5]
b = {9, 7, 6, 5, 1, 0}
[i for i, item in enumerate(a) if item in b]
inspired by #jamylak