Related
I'm very new to python (using python3) and I'm trying to add numbers from one list to another list. The only problem is that the second list is a list of lists. For example:
[[1, 2, 3], [4, 5, 6]]
What I want is to, say, add 1 to each item in the first list and 2 to each item in the second, returning something like this:
[[2, 3, 4], [6, 7, 8]]
I tried this:
original_lst = [[1, 2, 3], [4, 5, 6]]
trasposition_lst = [1, 2]
new_lst = [x+y for x,y in zip(original_lst, transposition_ls)]
print(new_lst)
When I do this, I get an error
can only concatenate list (not "int") to list
This leads me to believe that I can't operate in this way on the lists as long as they are nested within another list. I want to do this operation without flattening the nested list. Is there a solution?
One approach using enumerate
Demo:
l = [[1, 2, 3], [4, 5, 6]]
print( [[j+i for j in v] for i,v in enumerate(l, 1)] )
Output:
[[2, 3, 4], [6, 7, 8]]
You can use enumerate:
l = [[1, 2, 3], [4, 5, 6]]
new_l = [[c+i for c in a] for i, a in enumerate(l, 1)]
Output:
[[2, 3, 4], [6, 7, 8]]
Why don't use numpy instead?
import numpy as np
mat = np.array([[1, 2, 3], [4, 5, 6]])
mul = np.array([1,2])
m = np.ones(mat.shape)
res = (m.T *mul).T + mat
You were very close with you original method. Just fell one step short.
Small addition
original_lst = [[1, 2, 3], [4, 5, 6]]
transposition_lst = [1, 2]
new_lst = [[xx + y for xx in x] for x, y in zip(original_lst, transposition_lst)]
print(new_lst)
Output
[[2, 3, 4], [6, 7, 8]]
Reasoning
If you print your original zip it is easy to see the issue. Your original zip yielded this:
In:
original_lst = [[1, 2, 3], [4, 5, 6]]
transposition_lst = [1, 2]
for x,y in zip(original_lst, transposition_lst):
print(x, y)
Output
[1, 2, 3] 1
[4, 5, 6] 2
Now it is easy to see that you are trying to add an integer to a list (hence the error). Which python doesn't understand. if they were both integers it would add them or if they were both lists it would combine them.
To fix this you need to do one extra step with your code to add the integer to each value in the list. Hence the addition of the extra list comprehension in the solution above.
A different approach than numpy that could work even for lists of different lengths is
lst = [[1, 2, 3], [4, 5, 6, 7]]
c = [1, 2]
res = [[l + c[i] for l in lst[i]] for i in range(len(c))]
Say I have 2 lists:
list = [[1, 2, 3], [4, 5]]
a = 6
Is there anyway I can put a into the spot list[1][2]?
Yes, you can just do:
lst[1].append(a)
lst
# [[1, 2, 3], [4, 5, 6]]
To add an element, try:
my_list[1].append(a)
To replace an element:
my_list[1][1] = a # This will replace 5 by 6 in the second sub-list
Example of append:
>>> my_list = [[1, 2, 3], [4, 5]]
>>> a = 6
>>> my_list[1].append(a)
>>> my_list
[[1, 2, 3], [4, 5, 6]]
Example of replace:
>>> my_list = [[1, 2, 3], [4, 5]]
>>> a = 6
>>> my_list[1][1] = a
>>> my_list
[[1, 2, 3], [4, 6]]
Note: You should not use list to name your variable, because it would replace the built-in type list.
Instead of using list=[[1,2,3],[4,5]] (since list is a function in python) let's have
l=[[1,2,3],[4,5]]
Now there is no l[1][2] as yet.
If we try to access it we get
>>> l[1][2]
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
IndexError: list index out of range
We can append this element
l[1].append(a)
Now we can access it
>>> l[1][2]
6
and we can change it:
>>> l[1][2] = 44
>>> l
[[1, 2, 3], [4, 5, 44]]
I need to slice a list of lists:
A = [[1,2,3,4,5],[1,2,3,4,5],[1,2,3,4,5]]
idx = slice(0,4)
B = A[:][idx]
The code above isn't giving me the right output.
What I want is: [[1,2,3],[1,2,3],[1,2,3]]
Very rarely using slice objects is easier to read than employing a list comprehension, and this is not one of those cases.
>>> A = [[1,2,3,4,5],[1,2,3,4,5],[1,2,3,4,5]]
>>> [sublist[:3] for sublist in A]
[[1, 2, 3], [1, 2, 3], [1, 2, 3]]
This is very clear. For every sublist in A, give me the list of the first three elements.
With numpy it is very simple - you could just perform the slice:
In [1]: import numpy as np
In [2]: A = np.array([[1,2,3,4,5],[1,2,3,4,5],[1,2,3,4,5]])
In [3]: A[:,:3]
Out[3]:
array([[1, 2, 3],
[1, 2, 3],
[1, 2, 3]])
You could, of course, transform numpy.array back to the list:
In [4]: A[:,:3].tolist()
Out[4]: [[1, 2, 3], [1, 2, 3], [1, 2, 3]]
A = [[1,2,3,4,5],[1,2,3,4,5],[1,2,3,4,5]]
print [a[:3] for a in A]
Using list comprehension
you can use a list comprehension such as: [x[0:i] for x in A]
where i is 1,2,3 etc based on how many elements you need.
Either:
>>> [a[slice(0,3)] for a in A]
[[1, 2, 3], [1, 2, 3], [1, 2, 3]]
Or:
>>> [list(filter(lambda x: x<=3, a)) for a in A]
[[1, 2, 3], [1, 2, 3], [1, 2, 3]]
I am new in programming and Python is my First Language. it's only 4 to 5 days only to start learning. I just learned about List and slicing and looking for some example I found your problem and try to solve it Kindly appreciate if my code is correct.
Here is my code
A = [[1,2,3,4,5],[1,2,3,4,5],[1,2,3,4,5]]
print(A[0][0:3],A[1][0:3],A[1][0:3])
I'm a Python beginner and I'm currently going through Zed Shaw's course "Learn Python the Hardway"
So, in exercise 32 we are told:
How do you make a 2-dimensional (2D) list?
That's a list in a list like this: [[1,2,3],[4,5,6]]
I did this:
# Extra 1
global_list = [[1, 2, 3]]
inside_list = []
for i in global_list[0]:
inside_list.append(i)
global_list.append(inside_list)
print(global_list)
But I’m not entirely convinced that's the correct way. My question is: Is there a way to get the same result without ever leaving the for i in.... loop?
I also tried this, to no avail.
global_list = [[1, 2, 3]]
inside_list = []
for i in global_list[0]:
inside_list.append(i)
global_list.append(inside_list)
print(global_list)
Thanks in advance for your answers.
Lists can be appended and inserted into a list just like any other object, e.g:
outer_list = []
print(outer_list)
inner_list1 = [1, 2, 3]
outer_list.append(inner_list1)
print(outer_list)
inner_list2 = [4, 5, 6]
outer_list.append(inner_list2)
print(outer_list)
I am not sure if you already went over list comprehension. However, one nice way of doing what you are doing is:
>>> global_list = [[1,2,3]]
>>> global_list.append([i + 3 for i in global_list[0]])
>>> print global_list
[[1, 2, 4], [4, 5, 6]]
The question was "How do you make a 2-dimensional (2D) list?". The answer given was "That's a list in a list like this: [[1,2,3],[4,5,6]]". Literally, that's the answer:
>>> a = [[1, 2, 3], [4, 5, 6]]
>>> print a
[[1, 2, 3], [4, 5, 6]]
You can also do this:
>>> a = [[1, 2, 3]]
>>> a.append([4, 5, 6])
>>> a
[[1, 2, 3], [4, 5, 6]]
You don't need a for loop to append a list inside another list:
>>> a = [[1, 2, 3]]
>>> a[0]
[1, 2, 3]
>>> a.append(a[0])
>>> a
[[1, 2, 3], [1, 2, 3]]
However, this makes the second element of the list of lists the same as the first, so if you change one you change the other:
>>> a[0] is a[1]
True
>>> a[0][0] = 4
>>> a
[[4, 2, 3], [4, 2, 3]]
What you can do to make a copy of the list is list(a[0]):
>>> a = [[1, 2, 3]]
>>> a[0]
[1, 2, 3]
>>> a[0] is a[0]
True
>>> list(a[0])
[1, 2, 3]
>>> a[0] is list(a[0])
False
>>> a.append(list(a[0]))
>>> a
[[1, 2, 3], [1, 2, 3]]
>>> a[0] is a[1]
False
>>> a[0][0] = 4
>>> a
[[4, 2, 3], [1, 2, 3]]
Say I have a list of lists:
x = [[1,0,0,3],[1,1,1,1],[5,2,0,0],[4,3,0,1],[0,0,0,0]
How can I create a new list that only contains the non-zero terms of each list, such that
y = [[1,3],[1,1,1,1],[5,2],[4,3,1],[]]
In [23]: x = [[1,0,0,3],[1,1,1,1],[5,2,0,0],[4,3,0,1],[0,0,0,0]]
In [24]: y = [[el for el in l if el != 0] for l in x]
In [25]: y
Out[25]: [[1, 3], [1, 1, 1, 1], [5, 2], [4, 3, 1], []]
Alternatively,
In [28]: [filter(None, l) for l in x]
Out[28]: [[1, 3], [1, 1, 1, 1], [5, 2], [4, 3, 1], []]
Or using functools:
In [32]: map(functools.partial(filter, None), x)
Out[32]: [[1, 3], [1, 1, 1, 1], [5, 2], [4, 3, 1], []]
Use list comprehensions:
>>> [[i for i in j if i] for j in x]
[[1, 3], [1, 1, 1, 1], [5, 2], [4, 3, 1], []]
Also, note, that I fell back on the fact, that integers int are promoted to false only when they are equal to 0, and they are true of they are not equal to 0. It is worth contemplating if it would be wise to use if i != 0 instead of if i, as the former is more explicit and thus more Pythonic.
You can filter the lists:
y = map(lambda l: filter(None, l), x)
Or you can use partial:
from functools import partial
y = map(partial(filter, None), x)
x = [[1,0,0,3],[1,1,1,1],[5,2,0,0],[4,3,0,1],[0,0,0,0]]
print x
print 'id(x) ==',id(x)
for sublist in x:
print map(id,sublist)
for sublist in x:
for i in xrange(len(sublist)-1,-1,-1):
if sublist[i]==0:
del sublist[i]
print
print x
print 'id(x) ==',id(x)
for sublist in x:
print map(id,sublist)
With this code, you really ELIMINATE the zeros FROM THE INITIAL list without having to create another list, that is to say this code acts in place in x
The printing of id(x) and map(id,sublist) is done to show this way of modification:
the identities, that is to say the adresses of the elements of the sublists (for the ones that remain), and of the list x itself, are the same before and after the treatment
If the list is big, it may be interesting to modify it in place.
If it is not the case, you can use the other solutions that all create a new list object.
The indexes are run in the reverse sense thanks to xrange(len(sublist)-1,-1,-1) because if the list was explored from left to right, it would give erroneous result
Result
[[1, 0, 0, 3], [1, 1, 1, 1], [5, 2, 0, 0], [4, 3, 0, 1], [0, 0, 0, 0]]
id(x) == 18725984
[10021864, 10021876, 10021876, 10021840]
[10021864, 10021864, 10021864, 10021864]
[10021816, 10021852, 10021876, 10021876]
[10021828, 10021840, 10021876, 10021864]
[10021876, 10021876, 10021876, 10021876]
[[1, 3], [1, 1, 1, 1], [5, 2], [4, 3, 1], []]
id(x) == 18725984
[10021864, 10021840]
[10021864, 10021864, 10021864, 10021864]
[10021816, 10021852]
[10021828, 10021840, 10021864]
[]