I am trying to append a list of lists with Python but there is an error. My problem is just with append function. I explain my problem better. I am using a loop. The first time the append function works fine. But for the second time, the function does not work.
When we do the first loop, we get the right result:
list1 = [1,2,3]
list2 = [4,5,6]
list3 = []
list3.append(list1)
list3.append(list2)
print(list3)
result:
[[1, 2, 3], [4, 5, 6]]
With the second loop, append does not work correctly. One extra bracket.
liste4 = []
liste4.append(list3)
liste4.append(list1)
print(liste4)
result:
[[[1, 2, 3], [4, 5, 6]], [1, 2, 3]]
But the result I want is this:
[[1, 2, 3], [4, 5, 6], [1, 2, 3]]
Define list3 as an empty list and append to it :
list1 = [1,2,3]
list2 = [4,5,6]
list3 = []
list3.append(list1)
list3.append(list2)
print(list3)
Output :
[[1, 2, 3], [4, 5, 6]]
you could just do list3 = [list1, list2]
If you want it in a function, here is a go a a List of List creator, which may take multiple lists as the input:
def LoL(*lists):
out = [x for x in lists]
return out
list1 = [1,2,3]
list2 = [4,5,6]
list3 = [7,8,9]
list4 = LoL(list1,list2,list3)
list4
>>> [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
list1 = [1,2,3]
list2 = [4,5,6]
list3 = []
list3.append(list1)
list3.append(list2)
print(list3)
result:
[[1, 2, 3], [4, 5, 6]]
With the second loop:
liste4 = list3
liste4.append(list1)
print(liste4)
result:
[[1, 2, 3], [4, 5, 6], [1, 2, 3]]
Related
I have [1,2],[5],[2,7,9] and I want to make [[1,2],[5],[2,7,9]]. I tried some commands but they all return [1,2,5,2,7,9].
Can someone help?
Thanks
l1 = [1,2]
l2 = [5]
l3 = [2,7,9]
new_list = []
new_list = [l1] + [l2] + [l3]
print(new_list)
# or
new_list = []
new_list.append(l1)
new_list.append(l2)
new_list.append(l3)
print(new_list)
# or
new_list = []
new_list+=[l1]
new_list+=[l2]
new_list+=[l3]
print(new_list)
Output:
[[1, 2], [5], [2, 7, 9]]
[[1, 2], [5], [2, 7, 9]]
[[1, 2], [5], [2, 7, 9]]
I have a nested list in the form of [[1,2,3], [3,4,5], [8,6,2,5,6], [7,2,9]]
I would like to extract every first item into a new list, every second item into a new list and the rest into a new nested list:
a = [1,3,8,7] b = [2,4,6,2], c = [[3], [5], [2,5,6],[9]]
Is it possible to avoid using the for loop because the real nested list is quite large? Any help would be appreciated.
Ultimately, whatever your solution would be, you're gonna have to have a for loop inside your code and my advice would be to make it as clean and as readable as possible.
That being said, here's what I would propose:
arr = [[1,2,3], [3,4,5], [8,6,2,5,6], [7,2,9]]
first_arr, second_arr, third_arr = [], [], []
for nested in arr:
first_arr.append(nested[0])
second_arr.append(nested[1])
third_arr.append(nested[2:])
This is a naive, simple looped solution using list comprehensions, but see if it is fast enough for you.
l = [[1,2,3], [3,4,5], [8,6,2,5,6], [7,2,9]]
a = [i[0] for i in l]
b = [i[1] for i in l]
c = [i[2:] for i in l]
which returns:
>>a
[1, 3, 8, 7]
>>b
[2, 4, 6, 2]
>>c
[[3], [5], [2, 5, 6], [9]]
At the moment I cannot think a solution without for loops, I hope I will be able to update my answer later.
Here's a solution using for loops:
data = [[1,2,3], [3,4,5], [8,6,2,5,6], [7,2,9]]
list1 = []
list2 = []
list3 = []
for item in data:
else_list = []
for index, value in enumerate(item):
if index == 0:
list1.append(value)
elif index == 1:
list2.append(value)
else:
else_list.append(value)
list3.append(else_list)
print(list1)
print(list2)
print(list3)
Output
[1, 3, 8, 7]
[2, 4, 6, 2]
[[3], [5], [2, 5, 6], [9]]
Just for fun I share also a performance comparison, great job in using just one for loop Meysam!
import timeit
# a = [1,3,8,7] b = [2,4,6,2], c = [[3], [5], [2,5,6],[9]]
def solution_1():
data = [[1, 2, 3], [3, 4, 5], [8, 6, 2, 5, 6], [7, 2, 9]]
list1 = []
list2 = []
list3 = []
for item in data:
else_list = []
for index, value in enumerate(item):
if index == 0:
list1.append(value)
elif index == 1:
list2.append(value)
else:
else_list.append(value)
list3.append(else_list)
def solution_2():
arr = [[1, 2, 3], [3, 4, 5], [8, 6, 2, 5, 6], [7, 2, 9]]
first_arr, second_arr, third_arr = [], [], []
for nested in arr:
first_arr.append(nested[0])
second_arr.append(nested[1])
third_arr.append(nested[2:])
def solution_3():
l = [[1, 2, 3], [3, 4, 5], [8, 6, 2, 5, 6], [7, 2, 9]]
a = [i[0] for i in l]
b = [i[1] for i in l]
c = [i[2:] for i in l]
if __name__ == "__main__":
print("solution_1 performance:")
print(timeit.timeit("solution_1()", "from __main__ import solution_1", number=10))
print("solution_2 performance:")
print(timeit.timeit("solution_2()", "from __main__ import solution_2", number=10))
print("solution_3 performance:")
print(timeit.timeit("solution_3()", "from __main__ import solution_3", number=10))
Output
solution_1 performance:
9.580000000000005e-05
solution_2 performance:
1.7200000000001936e-05
solution_3 performance:
1.7499999999996685e-05
Suppose the nested list has unknown depth, then we'd have to use recursion
def get_elements(l):
ret = []
for elem in l:
if type(elem) == list:
ret.extend(get_elements(elem))
else:
ret.append(elem)
return ret
l = [1,2,[3,4],[[5],[6]]]
print(get_elements(l))
# Output: [1, 2, 3, 4, 5, 6]
Though it is not quite recommended to use unknown-depth nested lists in the first place.
I have this nested list:
list_1 = [[1,2,3], [1,2,3,4,5,6], [1,2,3,4,5,6,7,8,9]]
Count of sublist elements are always in mulitple of 3. I want to have 3 elments in each sublist. Desired output:
list_1 = [[1,2,3], [1,2,3], [4,5,6],[1,2,3], [4,5,6], [7,8,9]]
I can achieve this but first i have to flatten the list and then create the nested list. My code:
list_1 = [values for sub_list in lists_1 for values in sub_list] # flatten it first
list_1 = [list_1[i:i+3] for i in range(0, len(list_1), 3)]
Is there a way to skip the flatten step and get the desired result?
You can use a nested list comprehension:
list_1 = [[1,2,3], [1,2,3,4,5,6], [1,2,3,4,5,6,7,8,9]]
result = [i[j:j+3] for i in list_1 for j in range(0, len(i), 3)]
Output:
[[1, 2, 3], [1, 2, 3], [4, 5, 6], [1, 2, 3], [4, 5, 6], [7, 8, 9]]
Here is how you can use nested list comprehensions:
list_1 = [[1,2,3],[1,2,3,4,5,6],[1,2,3,4,5,6,7,8,9]]
list_1 = [a for b in list_1 for a in b]
list_1 = [list_1[i:i+3] for i in range(0,len(list_1),3)]
print(list_1)
Output:
[[1, 2, 3], [1, 2, 3], [4, 5, 6], [1, 2, 3], [4, 5, 6], [7, 8, 9]]
To put my two cents in, you could use two generator functions, one that flattens the list (with an arbitrarly nested list) and one that yields pairs of n values:
def recursive_yield(my_list):
for item in my_list:
if isinstance(item, list):
yield from recursive_yield(item)
else:
yield item
def taken(gen, number = 3):
buffer = []
for item in gen:
if len(buffer) < number:
buffer.append(item)
else:
yield buffer
buffer = []
buffer.append(item)
if buffer:
yield buffer
result = [x for x in taken(recursive_yield(list_1))]
Here are some examples of the in- / outputs:
list_1 = [[1,2,3], [1,2,3,4,5,6], [1,2,3,4,5,6,7,8,9]]
# -> [[1, 2, 3], [1, 2, 3], [4, 5, 6], [1, 2, 3], [4, 5, 6], [7, 8, 9]]
list_1 = [1,2,3,4,5,6]
# -> [[1, 2, 3], [4, 5, 6]]
list_1 = [1,2,[[1,2,4,5], [[[[1,10,9]]]]]]
# -> number = 5
# -> [[1, 2, 1, 2, 4], [5, 1, 10, 9]]
Thus, the solution is much more flexible than slicing alone.
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))]
I have this snippet of code:
list1 = [1, 2, 3]
list2 = list1
list1 = [4, 5, 6]
print(list2)
print(list1)
Which results in the following output:
[1, 2, 3]
[4, 5, 6]
Why is list2 not still pointed to [4, 5, 6]? I was under the impression that, since lists are mutable, the change would affect both list1 and list2, since in RAM both lists are pointed to the same sequence of items.
Any explanation would be appreciated.
I have added the reason as comments in the code :
# list1 variable points to the memory location containing [1, 2, 3]
list1 = [1, 2, 3]
# list2 variable made to point to the memory location pointed to by list1
list2 = list1
# list1 variable made to point to the memory location containing
# a new list [4, 5, 6], list2 still pointing to [1, 2, 3]
list1 = [4, 5, 6]
print(list2) # list2 prints [1, 2, 3]
print(list1) # list1 prints [4, 5, 6]
I'll go through the lines one by one:
# Define a list [1, 2, 3] and save it into list1 variable
list1 = [1, 2, 3]
# Define list2 to be equal to list1 (that is, list2 == list1 == [1, 2, 3])
list2 = list1
# Create a new list [4, 5, 6] and save it into list1 variable
# Notice, that this replaces the existing list1!!
list1 = [4, 5, 6]
# Print list2, which still points to the original list [1, 2, 3]
print(list2)
# Print the new list1, [4, 5, 6] that is
print(list1)
However, this:
list1 = [1, 2, 3]
list2 = list1
list1.append(4)
print(list2)
print(list1)
Will output:
[1, 2, 3, 4]
[1, 2, 3, 4]
Since we are editing the list1 (and therefore list2, they are mutable), not creating a new list and saving it under the variable name list1
The keyword here is create a new list, so you're not editing list1 in your example, you're actually changing the name list1 to point to a whole different list.
Lists are mutable. However, the line:
list1 = [4, 5, 6]
does not mutate the list object previously referenced by list1, it creates a brand new list object, and switches the list1 identifier to reference the new one. You can see this by looking at object IDs:
>>> list1 = [1, 2, 3]
>>> list2 = list1
>>> id(list1)
4379272472
>>> id(list2)
4379272472 # both reference same object
>>> list1 = [4, 5, 6]
>>> id(list1)
4379279016 # list1 now references new object
>>> id(list2)
4379272472 # list2 still references previous object