Dynamically appending one list into another - python

I have following very simple implementation in python
m = []
l = []
l.append('A')
l.append('B')
l.append('C')
m.append(l)
l.clear()
print(m) --> this gives empty list.
i tried
m = []
l = []
n = []
l.append('A')
l.append('B')
l.append('C')
n = l
m.append(n)
l.clear()
print(m) --> this gives empty list too
But when i do not clear l, print(m) give me desired list which is ['A','B','C']. Why python clears list m when i clear list l. they are 2 separate variables?

When you are passing a list to another list then it is taking its reference there
So when you cleared that list your original list's element is also cleared
Try this
m = []
l = []
l.append('A')
l.append('B')
l.append('C')
m.append(l.copy()) -> use list.copy()
l.clear()
print(m)

Both variables are reference pointing to the same object. to make a new list you need to use n = l[:]

An alternative to list.copy:
m.append(l[:])
or
m.append(list(l))
The will append to m a "freshly" created list.
In some situations also a deep copy of the object could be the right solution:
from copy import deepcopy
...
m.append(deepcopy(l))
...

Related

Differences between declaring a list & appending and list()

This below appends the s to the list l
s = pd.Series([1], name='foo')
l = []
l.append(s)
This only appends 1 to l
s = pd.Series([1], name='foo')
l = list(s)
How to implement the first script the best way without declaring a list and then appending?
[x] makes a list with x as an element.
list(x) makes a list produced by iterating over x. x has to be iterable, otherwise you'll get an error.
It is, in effect, [i for i in x], or
alist = []
for i in x:
alist.append(i)

How to save elements of a nested list in Python using a loop and deleting the list

I am trying to create a list of lists (nested list) taking the number of element and no of lists from users as b, a respectively. However, how can I save the temp_list into list_of_lists. Since I am deleting temp_list after appending it to list_of_list, elements from the later list are also being deleted.
a, b= map(int,input().split())
i = 0
list_of_lists = []
while i < b:
temp_list = []
temp_list.append(map(float, input().split()))
print(temp_list, i)
list_of_list.append(temp_list)
del temp_list[:]
i += 1
print(list_of_lists)
A couple of issues:
You shouldn't del temp_list[:] you are deleting the object you just added.
Your loop would be better as a for loop.
Your variable is called list_of_lists not list_of_list, so list_of_list.append() should throw a NameError
map in Py3 returns an iterator, so you need to turn it into a list, you could use temp_list.extend(map(...)) but you can just create it directly. Note: your first use of map(...) is unpacked into individual variables so works as expected.
Updated code:
a, b = map(int, input().split())
list_of_lists = []
for i in range(b):
temp_list = list(map(float, input().split()))
print(temp_list, i)
list_of_lists.append(temp_list)
in your code you are deleting the temp list each time
del temp_list[:]
instead of
a, b = map(int, input().split())
you can simply use it like
a, b = map(int, input())
and enter the input like 3,4 python will automatically get it as a tuple and will assign it to variable a,b respectively
a, b = map(int, input()) #3,4
list_of_lists = []
for i in range(b):
temp_list = list(map(float, input()))
print(temp_list, i)
list_of_lists.append(temp_list)
print (list_of_lists)

How to merge n lists together item by item for each list

I want to make one large list for entering into a database with values from 4 different lists. I want it to be like
[[list1[0], list2[0], list3[0], list4[0]], [list1[1], list2[1], list3[1], list4[1]], etc.....]
Another issue is that currently the data is received like this:
[ [ [list1[0], list1[1], [list1[3]]], [[list2[0]]], etc.....]
I've tried looping through each list using indexs and adding them to a new list based on those but it hasn't worked, I'm pretty sure it didn't work because some of the lists are different lengths (they're not meant to be but it's automated data so sometimes there's a mistake).
Anyone know what's the best way to go about this? Thanks.
First list can be constructed using zip function as follows (for 4 lists):
list1 = [1,2,3,4]
list2 = [5,6,7,8]
list3 = [9,10,11,12]
list4 = [13,14,15,16]
res = list(zip(list1,list2,list3,list4))
For arbitrtary number of lists stored in another list u can use *-notation to unpack outer list:
lists = [...]
res = list(zip(*lists))
To construct list of lists for zipping from you data in second issue use flatten concept to it and then zip:
def flatten(l):
res = []
for el in l:
if(isinstance(el, list)):
res += flatten(el)
else:
res.append(el)
return res
auto_data = [...]
res = list(zip(*[flatten(el) for el in auto_data]))
Some clarification at the end:
zip function construct results of the smallest length between all inputs, then you need to extend data in list comprehension in last code string to be one length to not lose some info.
So if I understand correctly, this is your input:
l = [[1.1,1.2,1.3,1.4],[2.1,2.2,2.3,2.4],[3.1,3.2,3.3,3.4],[4.1,4.2,4.3,4.4]]
and you would like to have this output
[[1.1,2.1,3.1,4.1],...]
If so, this could be done by using zip
zip(*l)
Make a for loop which only gives you the counter variable. Use that variable to index the lists. Make a temporary list , fill it up with the values from the other lists. Add that list to the final one. With this you will et the desired structure.
nestedlist = []
for counter in range(0,x):
temporarylist = []
temporarylist.append(firstlist[counter])
temporarylist.append(secondlist[counter])
temporarylist.append(thirdlist[counter])
temporarylist.append(fourthlist[counter])
nestedlist.append(temporarylist)
If all the 4 lists are the same length you can use this code to make it even nicer.
nestedlist = []
for counter in range(0,len(firstlist)): #changed line
temporarylist = []
temporarylist.append(firstlist[counter])
temporarylist.append(secondlist[counter])
temporarylist.append(thirdlist[counter])
temporarylist.append(fourthlist[counter])
nestedlist.append(temporarylist)
This comprehension should work, with a little help from zip:
mylist = [i for i in zip(list1, list2, list3, list4)]
But this assumes all the list are of the same length. If that's not the case (or you're not sure of that), you can "pad" them first, to be of same length.
def padlist(some_list, desired_length, pad_with):
while len(some_list) < desired_length:
some_list.append(pad_with)
return some_list
list_of_lists = [list1, list2, list3, list4]
maxlength = len(max(list_of_lists, key=len))
list_of_lists = [padlist(l, maxlength, 0) for l in list_of_lists]
And now do the above comprehension statement, works well in my testing of it
mylist = [i for i in zip(*list_of_lists)]
If the flatten concept doesn't work, try this out:
import numpy as np
myArray = np.array([[list1[0], list2[0], list3[0], list4[0]], [list1[1], list2[1], list3[1], list4[1]]])
np.hstack(myArray)
Also that one should work:
np.concatenate(myArray, axis=1)
Just for those who will search for the solution of this problem when lists are of the same length:
def flatten(lists):
results = []
for numbers in lists:
for output in numbers:
results.append(output)
return results
print(flatten(n))

Having trouble with printing mutated variable outside function (Python) [duplicate]

This question already has answers here:
having trouble with lists in python
(5 answers)
Closed 7 years ago.
def satisfiesF(L):
"""
Assumes L is a list of strings
Assume function f is already defined for you and it maps a string to a Boolean
Mutates L such that it contains all of the strings, s, originally in L such
that f(s) returns True, and no other elements
Returns the length of L after mutation
"""
result = []
for l in L:
result.extend(l)
L = list(result)
for i in result:
if i != 'a':
L.remove(i)
return len(L)
Basically what I am trying to do is mutate the list, L within the function. From my testing, it appears that the end result of L is exactly what I am looking for it to be, but when I print L outside of the function it just spits out the original, unmutated list. Can anyone help me fix this issue?
disclaimer: This is a homework problem, but I'm not looking for a solution to the whole problem - just this one issue. Thanks!
You are changing the name L to point to a new list inside the function, in line -
L = list(result)
This does not change the list outside the function, because only the local variable L changed to point to a new list, its previous reference was not changed (And the name/variable outside the function, that was used to call this function still points to the old list).
You should iterate over copy of result (created using result[:]) and remove from result , without changing the reference L points to. And then at end use L[:] = result , to make changes to the list reference that L points to.
Example -
list1 = ['a','b','c','d','e','f']
def satisfiesF(L):
result = []
for l in L:
result.extend(l)
for i in result[:]:
if i != 'a':
result.remove(i)
L[:] = result
return len(L)
satisfiesF(list1)
>>> 1
list1
>>> ['a']
def satisfiesF(L):
temp=L[:]
for x in temp:
if f(x)!=True:
L.remove(x)
return len(L)
def f(s):
return 'a' in s
replace
result = []
for l in L:
result.extend(l)
with
result =L[:]

How to delete elements from list of tuples?

I want to delete the list of tuple in python. I have the list
l = [('name','sam'),('age', 20),('sex', 'male')]
and another list of tuples
r = [('name','sam'),('age', 20)]
I am trying to delete those elements which are in r and l both. I am doing this:
for item in l:
if item in r:
del item
But the elements are not deleting. The output is nothing and when I print the modified list:
>>> l
Then original list is printing.
[('name','sam'),('age', 20),('sex', 'male')]
Please help me, how can I delete elements from list of tuples.
You can tranform both lists in sets and subtract them:
l = [('name','sam'),('age', 20),('sex', 'male')]
r = [('name','sam'),('age', 20)]
The following line will return only the elements that are in l but aren't in r:
set(l) - set(r)
This will return a list of items that are in l and not in r.
The difference between this solution and the solution to substract sets is that you do not lose information if you have duplicates inside your list. You lose this information with substracting sets
difference = [item for item in l if item not in r]
You can use a filter().
for item in filter(lambda x: x not in r, l):
# You can use your items here
# The list gets out of scope, so if there are no other references,
# the garbage collector will destroy it anyway
Or, if you need to use the list elsewhere too, you might also consider creating a new list instead, using a list comprehension:
l = [i for i in l if i not in r]
There are many approaches to go screw this problem:
find AND of those list by l and r for finding which are common in both then use to manipulate this in such a way: [x for x in l if x not in l and r ]. this will be little more efficient than above answers.
Correct marked answer will fall in some cases like what if len(l) < len(r). so for overcome this problem simply
list=[]
p = l and r
list.extend([ [x for x in l if x not in p ], [x for x in r if x not in p ]])
Hope it will fade out some uncovers.

Categories