concatenate lists in python - python

I have a 3x2 list called x and a 1x2 list called y:
x=[[1,2],[3,4],[5,6]]
and
y=[10,20]
my question is how to concatenate y to the end of x to end up with a 4x2 list like:
x=[[1,2],[3,4],[5,6],[10,20]]
I've tried this:
xx=[x,y]
but it gives me this which is not a 4x2 list:
xx=[[[1,2],[3,4],[5,6]],[10,20]]

>>> x = [[1, 2], [3, 4], [5, 6]]
>>> x
[[1, 2], [3, 4], [5, 6]]
>>> x.append([10, 20])
>>> x
[[1, 2], [3, 4], [5, 6], [10, 20]]
Or:
>>> x = [[1, 2], [3, 4], [5, 6]]
>>> x
[[1, 2], [3, 4], [5, 6]]
>>> x += [[10, 20]] # a list with a list as its only element
>>> x
[[1, 2], [3, 4], [5, 6], [10, 20]]

Given:
x = [[1,2],[3,4],[5,6]]
y = [10,20]
this:
x.append(y)
will give you:
[[1, 2], [3, 4], [5, 6], [10, 20]]
Note however that this modifies x.
If you don't want to modify x, this is another way:
xx = x + [y[:]]
setting xx to:
[[1, 2], [3, 4], [5, 6], [10, 20]]
We use y[:] rather than simply y in the above assignment because we want to create separate copy of y for xx so later, should (the original) y be modified it would not lead to changes in xx.

>>> x=[[1,2],[3,4],[5,6]]
>>> y=[10,20]
>>> x.append(y) # or x.append(list(y)) to append a shallow copy of y
>>> x
[[1, 2], [3, 4], [5, 6], [10, 20]]

If you want a new list:
z = x + [y]
Note, that using [y] makes the content a list within a list, so that this works.
If you want to modify x inplace, then:
x.append(y)

Although I don't use it often myself, I think it's worth mentioning the list's extend member function:
>>> x=[[1,2],[3,4],[5,6]]
>>> y=[10,20]
>>> x.extend([y])
>>> x
[[1, 2], [3, 4], [5, 6], [10, 20]]
http://docs.python.org/tutorial/datastructures.html#more-on-lists

Related

Mapping a list right in Python

I have a question on how to map correctly my list.
I have the following code:
class Bar():
def __init__(self, i, j):
self.i = i-1
self.j = j-1
For the following list:
bars = [Bar(1,2), Bar(2,3), Bar(3,4), Bar(4,5), Bar(5,1),Bar(1,4), Bar(2,4), Bar(4,6), Bar(6,5)]
But for my problem, I have an array like this:
elementsmat=[[1, 1, 2], [2, 2, 3], [3, 3, 4], [4, 4, 5], [5, 5, 1], [6, 1, 4], [7, 2, 4], [8, 4, 6], [9, 6, 5]]
I used the following code to obtain an array where I removed the first element of each list of the list and then transformed it into a list.
s= np.delete(elementsmat, 0, 1)
r = s.tolist()
Output: [[1, 2], [2, 3], [3, 4], [4, 5], [5, 1], [1, 4], [2, 4], [4, 6], [6, 5]]
So, how can I apply the Bar function to all the elements of my new array correctly? I did this but I got the following error.
bars = map(Bar,r)
__init__() missing 1 required positional argument: 'j'
I thought it could be because in the first one the list has () and in my list I have [], but I am not sure.
You can use itertools.starmap instead of map (after importing itertools). Your current way calls Bar([1, 2]). starmap unpacks the lists into arguments. A generator/list comprehension is also an option.
(Bar(*x) for x in r)
Now you see why it's called starmap.
You need to unpack the nested lists into the call to Bar():
l = list(map(lambda x: Bar(*x), r))
itertools.starmap does the same thing.
Or, you can use a list-comprehension:
l = [Bar(i, j) for i, j in r]
A built-in functional approach
lst = [[1, 2], [2, 3], [3, 4], [4, 5], [5, 1], [1, 4], [2, 4], [4, 6], [6, 5]]
map(Bar, *zip(*lst))

How to iterate two lists with different length together? [duplicate]

This question already has answers here:
Is there a zip-like function that pads to longest length?
(8 answers)
Closed 1 year ago.
I got two lists as shown below:
a = [[[1,2], [3, 4], [5,6]], [[8,9],[10,11]]]
b = [[[1,2], [1,3],[2,3],[3, 4],[4,6],[5,6]],[[8,9],[9,10],[10,11]]]
The values in both lists are a group of list of coordinate points. And you can notice that some of the coordinate points in list a are also shown in list b
My goal is to slice list b from the given coordinate points from list a and then append in a new list. Here is an example of what I expect to get.
Example
The first item of list a is [[1,2], [3, 4], [5,6]] which I named as a[0] while that of list b is [[1,2], [1,3],[2,3],[3, 4],[4,6],[5,6]] which I named as b[0]. Therefore, a[0] is a set of b[0]
I want to slice b[0] based on the values in a[0] into a new list which looks like [[[1,2],[1,3],[2,3],[3,4]],[[3, 4],[4,6],[5,6]]]. In other words, a[0] serves as the slicing index of b[0].
Below is my code, and I do not have any idea to execute the above statement.
for items in a:
c.append([])
for i,j in zip(range(len(items)),range(len(b))):
if i < len(items)-1:
L_i = b[j][b[j].index(a[i]):b[j].index(a[i+1])+1]
L_i = list(tuple(item) for item in L_i)
elif i == len(concave_points)-1:
temp1 = b[j][b[j].index(a[i]):]
temp2 =b[j][0:b[j].index(a[0])+1]
L_i = temp1 + temp2
L_i = list(tuple(item) for item in L_i)
And an error ValueError: [[1, 2], [3, 4], [5, 6]] is not in list is occured.
Thanks a lot.
You can zip the lists instead of their length and just slice the sublists by index
a = [[[1, 2], [3, 4], [5, 6]], [[8, 9], [10, 11]]]
b = [[[1, 2], [1, 3], [2, 3], [3, 4], [4, 6], [5, 6]], [[8, 9], [9, 10], [10, 11]]]
c = []
for aa, bb in zip(a, b):
for i in range(len(aa) - 1):
c.append(bb[bb.index(aa[i]):bb.index(aa[i + 1]) + 1])
print(c) # [[[1, 2], [1, 3], [2, 3], [3, 4]], [[3, 4], [4, 6], [5, 6]], [[8, 9], [9, 10], [10, 11]]]
And as on liner with list comprehensions
c = [bb[bb.index(aa[i]):bb.index(aa[i + 1]) + 1] for aa, bb in zip(a, b) for i in range(len(aa) - 1)]
a = [[1, 2], [3, 4], [5, 6]]
b = [[1, 2], [1, 3], [2, 3], [3, 4], [4, 6], [5, 6]]
union_a_b = []
a.extend(b)
for pair in a:
if pair not in union_a_b:
union_a_b.append(pair)
else:
continue
print(union_a_b)

Is there a way to combine a list like this?

assume that a and b are list.
a = [[1], [2]]
b = [[5, 6, 7], [3, 4, 5]]
I want to get a list which is
[[1,5,6,7], [2,3,4,5]]
Is there any way to do that effectively? Either lists or numpy array is OK.
zip is your friend:
>>> a = [[1], [2]]
>>> b = [[5, 6, 7], [3, 4, 5]]
>>> [x+y for x, y in zip(a, b)]
[[1, 5, 6, 7], [2, 3, 4, 5]]
You can also use map; the operator module provides a ready-made definition of lambda x,y: x + y for such uses.
>>> import operator
>>> list(map(operator.add, a, b))

Inserting an item after each item in a list (Python)

Say I have a list like this:
a = [[1, 2, 3], [4, 5, 6]]
filler = ['cat']
How could I get
b = [[1 ,2 ,3], ['cat'], [4, 5, 6], ['cat']]
As an output?
I prefer to use itertools for stuff like this:
>>> import itertools as it
>>> a = [[1, 2, 3], [4, 5, 6]]
>>> filler = ['cat']
>>> list(it.chain.from_iterable(it.izip(a, it.repeat(filler))))
[[1, 2, 3], ['cat'], [4, 5, 6], ['cat']]
I like the itertools-based solutions posted here, but here's an approach that doesn't require list comprehensions or itertools, and I bet it's super fast.
new_list = [filler] * (len(a) * 2)
new_list[0::2] = a
Here's an idea:
import itertools
a = [[1, 2, 3], [4, 5, 6]]
filler = ['cat']
print list(itertools.chain.from_iterable(zip(a, [filler] * len(a))))
Output:
[[1, 2, 3], ['cat'], [4, 5, 6], ['cat']]
Not pythonic but seems to work.
list = [[1, 2, 3], [4, 5, 6]]
result = []
for e in list:
result.append(e)
result.append(['cat'])
result.pop()
Found at this post:
Add an item between each item already in the list
something like this using itertools.islice() and itertools.cycle():
cycle() is used to repeat an item, and used islice() cut the number of repeatation to len(a), and then use izip() or simple zip() over a and the iterator returned by islice() ,
this will return list of tuples.
you can then flatten this using itertools.chain().
In [72]: a
Out[72]: [[1, 2, 3], [4, 5, 6]]
In [73]: b
Out[73]: ['cat']
In [74]: cyc=islice(cycle(b),len(a))
In [75]: lis=[]
In [76]: for x in a:
lis.append(x)
lis.append([next(cyc)])
....:
In [77]: lis
Out[77]: [[1, 2, 3], ['cat'], [4, 5, 6], ['cat']]
or:
In [108]: a
Out[108]: [[1, 2, 3], [4, 5, 6]]
In [109]: b
Out[109]: ['cat']
In [110]: cyc=islice(cycle(b),len(a))
In [111]: list(chain(*[(x,[y]) for x,y in izip(a,cyc)]))
Out[111]: [[1, 2, 3], ['cat'], [4, 5, 6], ['cat']]
a = [[1, 2, 3], [4, 5, 6]]
filler = ['cat']
out = []
for i in a:
out.append(i)
out.append(filler)
result = [si for i in zip(a, [filler]*len(a)) for si in i]
Try this, as a one-liner:
from operator import add
a = [[1, 2, 3], [4, 5, 6]]
filler = ['cat']
reduce(add, ([x, filler] for x in a))
> [[1, 2, 3], ['cat'], [4, 5, 6], ['cat']]
Or even simpler, without using reduce:
sum(([x, filler] for x in a), [])
> [[1, 2, 3], ['cat'], [4, 5, 6], ['cat']]
Both solutions do the same: first, create a generator of [element, filler] and then flatten the resulting stream of pairs. For efficiency, the first step is performed using generators to avoid unnecessary intermediate lists.
UPDATE:
This post is a textbook example of why a troll must not be fed in an online forum. See the comments to see what I mean. It's better to just ignore the troll.
python 3.2
a = [[1, 2, 3], [4, 5, 6]]
b = ['cat']
_=[a.insert(x,b) for x in range(1,len(a)*2,2)]

Return min/max of multidimensional in Python?

I have a list in the form of
[ [[a,b,c],[d,e,f]] , [[a,b,c],[d,e,f]] , [[a,b,c],[d,e,f]] ... ] etc.
I want to return the minimal c value and the maximal c+f value. Is this possible?
For the minimum c:
min(c for (a,b,c),(d,e,f) in your_list)
For the maximum c+f
max(c+f for (a,b,c),(d,e,f) in your_list)
Example:
>>> your_list = [[[1,2,3],[4,5,6]], [[0,1,2],[3,4,5]], [[2,3,4],[5,6,7]]]
>>> min(c for (a,b,c),(d,e,f) in lst)
2
>>> max(c+f for (a,b,c),(d,e,f) in lst)
11
List comprehension to the rescue
a=[[[1,2,3],[4,5,6]], [[2,3,4],[4,5,6]]]
>>> min([x[0][2] for x in a])
3
>>> max([x[0][2]+ x[1][2] for x in a])
10
You have to map your list to one containing just the items you care about.
Here is one possible way of doing this:
x = [[[5, 5, 3], [6, 9, 7]], [[6, 2, 4], [0, 7, 5]], [[2, 5, 6], [6, 6, 9]], [[7, 3, 5], [6, 3, 2]], [[3, 10, 1], [6, 8, 2]], [[1, 2, 2], [0, 9, 7]], [[9, 5, 2], [7, 9, 9]], [[4, 0, 0], [1, 10, 6]], [[1, 5, 6], [1, 7, 3]], [[6, 1, 4], [1, 2, 0]]]
minc = min(l[0][2] for l in x)
maxcf = max(l[0][2]+l[1][2] for l in x)
The contents of the min and max calls is what is called a "generator", and is responsible for generating a mapping of the original data to the filtered data.
Of course it's possible. You've got a list containing a list of two-element lists that turn out to be lists themselves. Your basic algorithm is
for each of the pairs
if c is less than minimum c so far
make minimum c so far be c
if (c+f) is greater than max c+f so far
make max c+f so far be (c+f)
suppose your list is stored in my_list:
min_c = min(e[0][2] for e in my_list)
max_c_plus_f = max(map(lambda e : e[0][2] + e[1][2], my_list))

Categories