Store all generated list from every loop in python - python

I am trying out python, basically newbie. What I wanted to do is to save or store all generated list into one list and access that list later. The list is generated from a loop.
Basically my code is:
def doSomething():
list = []
....some parsing procedures....
......
...here needed texts are extracted...
...so I am looping to extract all texts I need...
for a in something:
list.append(a)
After the first execution, list is now populated...
then the program proceeds into the next page which is basically the same structure and then again invoke the doSomething function.
I hope this is now clear..
Assuming the first, second and third loop etc. generated this:
1st loop: [1,2,3]
2nd loop: [4,5,6]
3rd loop: [7,8,9]
I wanted to save these lists into one list and access it later so that:
alllist = [1,2,3,4,5,6,7,8,9]
How can I achieve this?

you might pass the values to another function like:
def newFunction(args, results =[]):
result.append(args)
return result
then call the function that generates list:
doSomething()
newFunction(doSomething())
if we print newFunction(doSomething()), we will see the appended lists from doSomething function

Identation is important in python. Your code does not have proper Indentation. Other programming languages use { and } to group statements whereas Python uses whitespace.
for a in something:
list.append(a)
for b in something2:
list.append(b)
However, I would recommend using something + something2 directly.

This should help:
lst = [1, 2, 3]
lst.extend([4, 5, 6])
lst.extend([7, 8, 9])
# [1, 2, 3, 4, 5, 6, 7, 8, 9]

You can store your first three lists from the for loop in variables, and then you can do a for loop for each list, and append it to a new list in order to get the output that you are seeking.
first_list = [1,2,3]
second_list = [4,5,6]
third_list = [7,8,9]
new_list = []
for number in first_list:
new_list.append(number)
for number in second_list:
new_list.append(number)
for number in third_list:
new_list.append(number)
print(new_list)
The output now in new_list is:
[1, 2, 3, 4, 5, 6, 7, 8, 9]

you may use extend method:
def doSomething(something):
list = []
for a in something:
list.append(a)
# ....this loop for some definite number...
return list
allist = []
allist.extend(doSomething(smt1))
allist.extend(doSomething(smt2))
allist.extend(doSomething(smt3))

What you really need (I think) is what other languages might call a 'static'. There are several solutions to this, including writing a class. I often use a closure for this.
In this example, the first function called, initial sets-up four attributes, a localList (don't call a variable list, it masks the list class), start, and two inner functions. References to those functions are returned (without being called) and they each have localList retained in their context.
The use of nonlocal (Python 3 required) is required to indicate the context of start.
The advantage of this is that the actual mechanism is encapsulated, and we don't have globals. If you had variables called localList, start, inner, and inner_get elsewhere in the program they would not collide.
def initial():
localList = []
start = 1
def inner():
nonlocal start
for a in range(start, start + 3):
localList.append(a)
start += 3
def inner_get():
return localList
return inner, inner_get
# get the function references
doSomething, getIt = initial()
for i in range(3):
doSomething()
# get the list
print(getIt())
# or
alllist = getIt()
Gives:
[1, 2, 3, 4, 5, 6, 7, 8, 9]
Yes its a bit complicated, but its a useful technique to get your head around if you can.

I had figure it out, I have to create a function that store all the lists during the loops:
def funcThatStoreList(args, result =[]):
result.append(args)

Related

Creating lists while code is running and adding them to an List Parent

I am trying to create lists based on a value given by the user input and then I would like to add those lists created to a Parent list where they all can be accessed and used.
For example, I want the for loop to grab the number entered by the user, and based on that number it needs to create lists numbered from 1 to whatever they chose. At the end of each repetition I would like to add the created list to a parent list.
Here is what I have so far, I am struggling in adding them to the parent list I guess.
lists = int(input("How many lists do you want? "))
varname = 'iteration_number_'
parent_list = []
for i in range(lists):
iteration_number = i+1 #So it does not start from 0
iteration_names = varname + str(iteration_number) #merging the name and the number
x = parent_list.append(exec(f"{iteration_names} = []")) #creating lists with that name
try:
iteration_number_1.append("Cow") # appends Cow to the first list if existing
iteration_number_2.append("Moo") # appends Moo to the first list if existing
print(iteration_number_1)
print(iteration_number_2)
except NameError:
pass
print(parent_list)
parent_list[0].append("This is list iteration_number_1 but I'm not working")
The last part of the code doesn't work as planned. In my head when I print parent_list I should get [[iteration_number_1], [iteration_number_2]] and they can be accessed like this
parent_list[0].append("Hello") #appending to the iteration_number_1 list
Does anyone know a better idea? or how to make this idea work?
The programmers call them nested lists:
myNestedList = [
[1, 2, 3],
[4, 5, 6],
[7, 8, 9]
]
You can access the inner lists this way:
>>> myNestedList[0] # Get the first row
[1, 2, 3]
>>> myNestedList[0][2]
3
You can append elements to the inner lists this way:
>>> myNestedList[0].append(10)
>>> myNestedList
[[1, 2, 3, 10], [4, 5, 6], [7, 8, 9]]
I saw you are using strings as keys instead of integers, this way:
iteration_names = varname + str(iteration_number) #merging the name and the number
x = parent_list.append(exec(f"{iteration_names} = []")) #creating lists with that name
In your case it's a bad idea, but you could use dictionaries, this way:
myDict: dict = {
"iteration_name_1": <first-element-of-the-list>,
"iteration_name_2": <second-el...>
}
You can access the dictionary this way:
>>> myDict['iteration_name_1']
<first-element...>
If you tried this at the end of the program:
parent_list[0].append(iteration_name_1)
and it didn't work, I would suggest to create the lists by name this way (if you really need to call them with names like 'name_x'):
>>> locals()['iteration_name_1'] = []
>>> iteration_name_1
[]
It has nothing to do with the question, but...
for i in range(lists):
iteration_number = i+1 #So it does not start from 0
...you should know that a better practice is to do this:
for i in range(1, lists):
# i starts from 1
All and all...
The best practice would be doing this way:
for i in range(lists):
parent_list.append([])
try:
parent_list[0].append('Cow')
parent_list[1].append('Moo')
except IndexError: # There is a different exception for an element not found in parent_list
pass
You could try to a dictionary with the key as a string to the iteration number and the value as a list:
d = {}
d["iteration_number_1"] = []
...
d["iteration_number_1"].append("hello")

Merge two lists that are generated by a python code

I know we can merge two lists by using something like final_list= list1 + list2 but if the lists are generated by a python code and they don't have a variable associated with them like list1 and list2, how can we merge them? Say, my code does something like print output to give:
[1,2,3,4]
[2,0,5,6]
I'd like to merge them so I can get unique values using set(final_list). But how do I get the final_list?
PS- My code can return multiple lists. It is not restricted to two.
def somefunc(param):
#does something
return alist,blist
my_alist,my_blist = somefunc(myparam)
print my_alist, my_blist
#prints both lists.
When you return multiple values from a function they are returned in a tuple. You can easily unpack the tuple
You can either modify the function which is generating output, or the harder way being you manually convert it into a string and then into a set.
list = []
strings_of_list = output.split('\n')
for string in strings_of_list:
values = string[1:-1].split(',')
for val in values:
list+=[int(val)]
set(list)
Assign a variable to a function. Taking the lists the function generated, join them together in another variable. Just make sure that your function returns the generated list, and doesn't just print it out.
# my_list_generator returns two values.
>>> a, b = my_list_generator()
>>> a
[1, 2, 3, 4]
>>> b
[2, 0, 5, 6]
>>> final_list = a + b
>>> final_list
[1, 2, 3, 4, 2, 0, 5, 6]
Cross all that out! Now that I know the function can return multiple objects, let do this (with a little list comprehension):
lists = [i for i in my_list_generator()]
# lists might look like [[1, 2, 3, 4], [2, 0, 5, 6]]
# And now use a for loop to get each value
final_list = []
for sublist in lists:
final_list.extend(sublist)
# final_list will look like [1,2,3,4,2,0,5,6]
Also, if you don't want duplicates, just do one more thing:
real_final_list = [i for i in final_list if i not in real_final_list]
If I understand correctly:
You have a function (let's call it listGen() for now) which returns some number of lists. Now, you want to put these list together into one big list, final_list.
You could do the following:
# listGen defined earlier
final_list = []
for i in listGen():
final_list += i
unique_values = set(final_list) # or whatever you wanted to do with it
Since listGen returns a tuple, we can loop over its contents, those being the lists you want to append to each other.

Remove matching items in a list

Sorry if this is a duplicate question, I searched and couldn't find anything to help.
I'm currently trying to compare two lists. If there are any matching items I will remove them all from one of the lists.
However the results I have are buggy. Here is a rough but accurate representation of the method I'm using:
>>> i = [1,2,3,4,5,6,7,8,9]
>>> a = i
>>> c = a
>>> for b in c:
if b in i:
a.remove(b)
>>> a
[2, 4, 6, 8]
>>> c
[2, 4, 6, 8]
So I realised that the main issue is that as I remove items it shortens the list, so Python then skips over the intermediate item (seriously annoying). As a result I made a third list to act as an intermediate that can be looped over.
What really baffles me is that this list seems to change also even when I haven't directly asked it to!
In python, when you write this:
i = [1,2,3,4,5,6,7,8,9]
You create an Object (in this case, a list) and you assign it to the name i. Your next line, a = i, tells the interpreter that the name a refers to the same Object. If you want them to be separate Object you need to copy the original list. You can do that via the slicing shorthand, i[:], or you can use a = list(i) to be more explicit.
The easiest way to do this is use a set to determine shared items in a and b:
for x in set(a).intersection(b):
a.remove(x)
Your statements a = i and c = a merely make new names that reference the same object. Then as you removed things from a, it's removed from b and i, since they are the same object. You'll want to make copies of the lists instead, like so
a = i[:]
c = a[:]
a = i Doesn't make a copy of a list, it just sets another variable, i to point at your list a. Try something like this:
>>> i = [1, 2, 3, 2, 5, 6]
>>> s = []
>>> for i in t:
if i not in s:
s.append(i)
>>> s
[1, 2, 3, 5, 6]
You can also use set which guarantees no duplicates, but doesn't preserve the order:
list(set(i))

Popping all items from Python list

I'm wondering if there is a way to "pop all" items from a list in Python?
It can be done in a few lines of code, but the operation seems so simple I just assume there has to be a better way than making a copy and emptying the original. I've googled quite a bit and searched here, but to no avail.
I realize that popping all items will just return a copy of the original list, but that is exactly why I want to do just that. I don't want to return the list, but rather all items contained therein, while at the same time clearing it.
class ListTest():
def __init__(self):
self._internal_list = range(0, 10)
def pop_all(self):
result, self._internal_list = self._internal_list[:], []
return result
# ... instead of:
# return self._internal_list.pop_all()
t = ListTest()
print "popped: ", t.pop_all()
print "popped: ", t.pop_all()
... which of course returns the expected:
popped: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
popped: []
This is exactly how it's done. The only substantial improvement that I can think of is to empty the list in-place:
def pop_all(l):
r, l[:] = l[:], []
return r
The difference between this and your version is the behavior on a list that is referenced from various places:
>>> a = [1, 2, 3]
>>> b = a
>>> pop_all(a)
[1, 2, 3]
>>> b
[]
In fact, why not just
def pop_all(self):
result, self._internal_list = self._internal_list, []
return result
... if you are reassigning self._internal_list anyway, why not just return the old one instead of copying it?
I had a need for this just now, and decided on using a list comprehension rather than have a subclass or subroutine like this:
popped = [l.pop(0) for item in list(l)]

How to check if a list exists in python?

I have a networkx graph.
I am adding nodes by adding edges
G.add_edge(route[i-1],route[i]);
Now once the node is created by directly adding edges,
I add a list named
G.node[route[i]]['position'] = list()
and I append positions to it when I get same nodes again and again
G.node[route[i]]['position'].append( i - 3 )
Now when I want to append how do I check whether the list exist?
does doing
G.node[route[i]]['position'] = list()
clear the list of already existing elements?
edit----- my earlier question was confusing
I want to keep adding to the list
but I cant append unless a list exists, right?
So I have to do do
G.node[route[i]]['position'] = list() in my loop
So next time when I want to add to the same list in another loop instance how do I know that a list exists for G.node[route[i]]['position'] and I dont have to create it again.
edit-----
I think my list itself is a key here
so I did
if not 'position' in G.node[route[i]]:
and it works
G.node[route[i]]['position'] = list() will leave the slot G.node[route[i]]['position'] holding an empty list, but it will not affect the list that it previously held, which other objects may have a reference to.
Instead, use: del l[:] to empty the list.
If you want to have a list automatically created, use collections.defaultdict to have newly created entries default to a list.
Yes, that clears the existing list. You could try
G.node[route[i]].setdefault('position', []).append(...)
whenever you want to append elements.
Not sure if this is what you mean, but assigning list() should make sure that there is a list to append to. If there's already a list the assignment creates a new one (see answer of Marcin). Test:
>>> a = list()
>>> for i in range(10):
... a.append(i)
...
>>> a
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> b = a
>>> b
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> a = list()
>>> a
[]
>>> b
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
Just use get:
if G.node[route[i]].get('position') is None:
G.node[route[i]]['position'] = list()
else:
G.node[route[i]]['position'].append(stuff)
1) How do I check whether the list exist?
Use isinstance() and do something like:
if not ininstance(G.node[route[i]]['position'], list):
G.node[route[i]]['position'] = list()
G.node[route[i]]['position'].append(i - 3)
Or use type like:
if not type(G.node[route[i]]['position']) is list
I must say that this kind of checking is rather un-pythonic, usually you should know what G.node[route[i]]['position'] was before becoming a list and check for that.
For example, if it was None you could do (assuming that the key 'position' exists, otherwise just call get('position')):
if G.node[route[i]]['position'] is None:
G.node[route[i]]['position'] = list()
G.node[route[i]]['position'].append(i - 3)
2) Does doing .. = list() clear the list of already existing elements?
The answer is No.
list() will instantiate a new empty list.
You may want to take a look at this SO question: How to empty a list in Python?.
In short:
G.node[route[i]]['position'][:] = []
will clear your list.

Categories

Resources