How do I check if a list is a subset of a bigger list.
i.e.
a = [1,2,3] is a subset of b = [1,2,3,4,5,6]
Can I do something like
if a all in b
http://docs.python.org/library/stdtypes.html#set.issubset
set(a).issubset(set(b))
>>> a = set([1, 2, 3])
>>> b = set([1, 2, 3, 4, 5, 6])
>>> a.issubset(b)
True
or
>>> a = [1, 2, 3]
>>> b = [1, 2, 3, 4, 5, 6]
>>> all(map(lambda x: x in b, a))
True
>>> a = [1, 2, 3, 9]
>>> all(map(lambda x: x in b, a))
False
or (if the number of elements is important)
>>> a = [1, 1, 2, 3]
>>> all(map(lambda x: a.count(x) <= b.count(x), a))
False
mostly like the other answers, but I do prefer the generator syntax here, seems more natural and it's lazily evaluated:
if all(x in b for x in a):
pass
if you care about the number of repeated elements, this option seems nice, and you could optimize it sorting c and using bisect:
def all_in(a, b)
try:
c = b[:]
for x in a: c.remove[x]
return True
except:
return False
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!
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]
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
Suppose I have a list x = [1,2,3] and I want to output every other value than the indexed one, is there a list operation I can use?, ie: x[0]=> [2,3], x[1] => [1,3], x[2] =>[1,2] ?
You could use this:
def exclude(l, e):
return [v for i, v in enumerate(l) if i != e]
>>> exclude(range(10), 3)
[0, 1, 2, 4, 5, 6, 7, 8, 9]
You could do it with a slice, but I'd be tempted to try:
a = [1, 2, 3]
b = a[:]
del b[1]
edit
The above does "technically" use a slice operation, which happens to be on list objects in effect a shallow-copy.
What's more flexible and shouldn't have any downsides is to use:
a = [1, 2, 3]
b = list(a)
del b[1]
The list builtin works on any iterable (while the slice operation [:] works on lists or those that are indexable) so that you could even extend it to constructs such as:
>>> a = '123'
>>> b = list(a)
>>> del b[0]
>>> ''.join(b)
'23'
You could use x[:i] + x[i+1:]:
In [8]: x = [1, 2, 3]
In [9]: i = 0
In [10]: x[:i] + x[i+1:]
Out[10]: [2, 3]
Depending on the context, x.pop(i) might also be useful. It modifies the list in place by removing and returning the i-th element. If you don't need the element, del x[i] is also an option.
>>> x = [1, 2, 3]
>>> x[:1] + x[2:]
[1, 3]
my_list = [1, 2, 3]
my_list.remove(my_list[_index_]) #_index_ is the index you want to remove
Such that: my_list.remove(my_list[0]) would yield [2, 3],
my_list.remove(my_list[1]) would yield [0, 3], and
my_list.remove(my_list[2]) would yield [1, 2].
So you want every value except the indexed value:
Where i is the index:
>>> list = [1,2,3,4,5,6,7,8]
>>> [x for x in list if not x == list[i]]
This will give you a list with no instances of the i't element, so e.g.:
>>> i = 2
>>> list = [1,2,3,4,5,6,7,1,2,3,4,5,6,7]
>>> [x for x in list if not x == list[i]]
[1, 2, 4, 5, 6, 7, 1, 2, 4, 5, 6, 7]
note how 3 is not in that list at all.
Every other is
x[::2], start at 0
x[1::2], start at 1
I have a list and I want to use a certain function only on those entries of it that fulfills a certain condition - leaving the other entries unmodified.
Example: Say I want to multiply by 2 only those elements who are even.
a_list = [1, 2, 3, 4, 5]
Wanted result:
a_list => [1, 4, 3, 8, 5]
But [elem * 2 for elem in a_list if elem %2 == 0] yields [4, 8] (it acted as a filter in addition).
What is the correct way to go about it?
Use a conditional expression:
[x * 2 if x % 2 == 0 else x
for x in a_list]
(Math geek's note: you can also solve this particular case with
[x * (2 - x % 2) for x in a_list]
but I'd prefer the first option anyway ;)
a_list = [1, 2, 3, 4, 5]
print [elem*2 if elem%2==0 else elem for elem in a_list ]
or, if you have a very long list that you want to modify in place:
a_list = [1, 2, 3, 4, 5]
for i,elem in enumerate(a_list):
if elem%2==0:
a_list[i] = elem*2
so, only the even elements are modified
You could use lambda:
>>> a_list = [1, 2, 3, 4, 5]
>>> f = lambda x: x%2 and x or x*2
>>> a_list = [f(i) for i in a_list]
>>> a_list
[1, 4, 3, 8, 5]
Edit - Thinking about agf's remark I made a 2nd version of my code:
>>> a_list = [1, 2, 3, 4, 5]
>>> f = lambda x: x if x%2 else x*2
>>> a_list = [f(i) for i in a_list]
>>> a_list
[1, 4, 3, 8, 5]