How to shorten a code to make multiple lists? - python

I'm making 12 lists that undergo the same process. Unfortunately, I can't figure out how to make them all do this in a loop, and I've been forced to repeat the same code 12 times and take up a giant chunk of text.
Here's a small portion of the code I've had to write.
l1 = []
l1.append(random.choice(easy))
if "none" in l1:
l1.remove("none")
else:
psblnsrs.append(l1[0])
easy.remove(l1[0])
l1.append(random.choice(special))
if "none" in l1:
l1.remove("none")
elif len(l1) >1:
usblhks.append(l1[1])
else:
usblhks.append(l1[0])
while sum(len(l1) for l1 in l1) < 12:
l1.append(random.choice(junk))
random.shuffle(l1)
l2 = []
l2.append(random.choice(easy))
if "none" in l2:
l2.remove("none")
else:
psblnsrs.append(l2[0])
easy.remove(l2[0])
l2.append(random.choice(special))
if "none" in l2:
l2.remove("none")
elif len(l2) >1:
usblhks.append(l2[1])
else:
usblhks.append(l2[0])
while sum(len(l2) for l2 in l2) < 12:
l2.append(random.choice(junk))
random.shuffle(l2)
Keep in mind, there are twelve lists that need to be made, this is only two.
I'm not too familiar with coding massive loops and naming variables properly. I want something like this:
for i in range(12):
l(i) = []
l(i).append ...
Is there a way to make this work or a similar way to make this work?
Also, if the code is hard to understand, the source material is here.

Functions might come in handy
def make_list(inp_list1=psblnsrs, inp_list2=usblhks, easy_list=easy, special_list=special, junk_list=junk):
l1 = []
l1.append(random.choice(easy_list))
if "none" in l1:
l1.remove("none")
else:
psblnsrs.append(l1[0])
easy.remove(l1[0])
l1.append(random.choice(special_list))
if "none" in l1:
l1.remove("none")
elif len(l1) >1:
usblhks.append(l1[1])
else:
usblhks.append(l1[0])
while sum(len(l1) for l1 in l1) < 12:
l1.append(random.choice(junk_list))
return random.shuffule(l1)
l = []
for i in range(12):
l.append(make_list())

I think you could probably do it pretty much just like your are doing it.
lists = []
for list in lists:
list = []
list.append(random.choice(easy))
if "none" in list:
list.remove("none")
else:
psblnsrs.append(list[0])
easy.remove(list[0])
list.append(random.choice(special))
if "none" in list:
list.remove("none")
elif len(list) >1:
usblhks.append(list[1])
else:
usblhks.append(list[0])
while sum(len(list) for list in list) < 12:
list.append(random.choice(junk))
random.shuffle(list)
Unless I'm missing something about how your code works upstream, you should just be able to do that, you will end up with a list of lists, which you can reference by their index. (e.g. lists(2))

Consider the following code
#Create a list to contain lists
myLists = []
#Add to our list 12 empty lists
for i in range(12):
myLists.append([])
#Loop over each list and add 12 to each list.
for currentList in myLists:
currentList.append(12)
#Print out the results
print(myLists)
by using for currentList in myLists, we can iterate over each list in our "list of lists" and perform operations on the currentList before moving on to the next one. Your code that therefore perform the same operations on each list in turn.

As khelwood pointed out, a better data structure for your twelve lists is to just store them in another list. That way you can access them with super_list[0], super_list[1], and more importantly you can iterate over them with for sublist in super_list: ... rather than having to refer to them explicitly at all.
That way, you only have to write your logic once. What you're looking to do is define a function:
def list_update(current_list):
'''
List management logic code here.
'''
...
return current_list
Then in the main logic of your code:
for sub_list in super_list:
sub_list = list_update(sub_list)
This way, when you have to make a change to the way you're handling those lists, you don't have to write the change 12 times, you only have to write it once.

Related

Generate a while loop [duplicate]

This question already has answers here:
Flatten an irregular (arbitrarily nested) list of lists
(51 answers)
Closed 2 days ago.
I'm trying to create a while loop for my code. The idea is not to use so many "for" loops to put it into a function
int_list = [[[1]],2,[[[[3]]]]]
for i in int_list:
if type(i) != list:
list_of_lists.append(i)
else:
for a in i:
if type(a) != list:
list_of_lists.append(a)
else:
for j in a:
if type(j) != list:
list_of_lists.append(j)
else:
for h in j:
if type(h) != list:
list_of_lists.append(h)
else:
for r in h:
if type(r) != list:
list_of_lists.append(r)
Expected Output
list_of_lists = [1,2,3]
One way to reduce for loop is to create a recursive function.
The function recursively calls itself on that sublist(i) by passing it as an argument to helper(). The resulting list is then extended to the result list using the extend() method.
If it's instance is not a list. it runs else part. appending value into the lis
Code:
def helper(lis):
res=[]
for i in lis:
if isinstance(i, list):
res.extend(helper(i))
else:
res.append(i)
return res
int_list=[[[1]], 2, [[[[3]]]]]
list_of_lists=helper(int_list)
print(list_of_lists)
Output:
[1,2,3]
A recursive function is the ideal way to flatten a list like this. If you really want to do it in a single while loop, though, it is possible, by creating a stack to help you keep track of where you are in each sublist.
This happens automatically for you when you define and call a recursive function; every call to the function puts all the function's local variables onto a "stack", just like the code below puts the current list and index onto a list called stack every time a new sublist is discovered.
int_list = [[[1]],2,[[[[3]]]]]
flat_list = []
stack = []
i = 0
while True:
if i >= len(int_list):
# We're at the end of this sublist,
# so go back to the stack to pick up where we left off.
if not stack:
break # all done!
int_list, i = stack.pop()
elif isinstance(int_list[i], list):
# Keep track of the current list and the next item
# for us to look at, and then start looking at this sublist.
stack.append((int_list, i+1))
int_list, i = int_list[i], 0
else:
# We found a scalar item! Add it to the flat list.
flat_list.append(int_list[i])
i += 1
assert flat_list == [1, 2, 3]

I can't find documentation on how to iterate across items in two lists serially, just in parallel

I want to execute the same effect as the below code, but there has to be a way to do it in one (possibly nested) for loop, right?
list_1 and list_2 have a bunch of numbers. I need to sort the contents into a list for odds and a list for evens. The below works, but seems inelegant. Is there a way to combine the two for loops into one?
# parse list_1
for i in list_1:
if i % 2 == 0:
list_even.append(i)
else:
list_odd.append(i)
# parse list_2
for i in list_2:
if i % 2 == 0:
list_even.append(i)
else:
list_odd.append(i)
Hello please try that it much faster and easier no need to write same operation for each list
def anyoperation(i):
if i % 2 == 0:
list_even.append(i)
else:
list_odd.append(i)
list(map(anyoperation,list_1))
list(map(anyoperation,list_2))

Changing(replacing) a value in a list without using range(len())

My purpose is to change the value of the elements 3 and 4 to 4 and 3 and I have written a function that takes a list, first number and second number as arguments:
def pre9(the_list, value_to_replace, the_replacing_value):
for i in the_list:
if i == value_to_replace:
value_to_replace = the_replacing_value
elif i == the_replacing_value:
the_replacing_value = value_to_replace
return the_list
I then assign a test-case to a variabel and then print it:
test_pre9 = pre9([1,2,3,4,5,7,3,4], 3, 4)
print(test_pre9)
The result is: [1,2,3,4,5,7,3,4]
I expect it to be: [1,2,4,3,5,7,4,3]
I have for a long time ago written a code that accoplishes this task:
def uppgift_9():
the_list = [3,5,8,9,4,5]
for i in range(len(the_list)-1):
temp = the_list[3]
the_list[3] = the_list[4]
the_list[4] = temp
return the_list
But I've read in many places that using range(len()) is not "pythonic" and it is possible to do anything without using it.
Does anyone know why my code fails?
You don't actually change the item in the list, try this:
def pre9(the_list, value_to_replace, the_replacing_value):
for i, value in enumerate(the_list):
if value == value_to_replace:
the_list[i] = the_replacing_value
elif value == the_replacing_value:
the_list[i] = value_to_replace
return the_list
Now the list will have the actually items changed to what you wanted it to be. Enumerate() returns the index and value of an item in a list, it's very handy! And indeed, the range(len()) is not very pythonic and is usually used when people jump from other languages like Java, C# etc. Using enumerate() is the correct 'pythonic' way of achieving this.

Divert an entry into a list into another list if list gets to big

list.append(elapse):
if len(list) > 50:
raise Exception(list_2.append(elapse))
else:
list.append(elapse)
I have no idea how to format this, I just want it so that once list[] gets to big the new entries are diverted into list_2[], my original code doesn't have raise Exception() just list_2.append(elapse). I'm only in highschool, week 6 of computer science so I don't know too much jargon.
You can simply use an if / else construct as so:
if len(lst_1) >= 50:
lst_2.append(elapse)
else:
lst_1.append(elapse)
But think about your use case. Consider these questions:
Why is your list size capped? Is this something that can be accounted for downstream?
Will you have an indefinite number of lists? If so, consider using a dictionary of lists, or list of lists.
simply make a 2 layer list:
mainList = [] # create the mainList to hold each list with 50 values in
while True:
innerList = [] # create the list to hold the 50 items
for x in range(50): # run through your code 50 times to add 50 items to the list
yourValue = 0 # your code to add to the list
innerList.append(yourValue) # add the value
mainList.append(innerList) # add the list of 50 values to the mainList
This means you can have an endless number of 50 item lists rather than limit yourself to a hard-coded number of lists :)
First off, you cannot name a list because list is a python built in name.
So call them list1 and list2 (Anything but list.
Of course you do not raise an exception like you did in python.
list1 = []
list2 = []
if len(list1) > 50: # Check if list1 is full
list_2.append(elapse) # append to list2 if list1 is full
else:
list1.append(elapse) #if list1 is not > 50, append to list1
if you wish you can use elif to check the len of list2.
You can have as many elif statements as you please but else is always last.
list1 = []
list2 = []
if len(list1) > 50:
list_2.append(elapse)
elif list2 > 50:
print('OUT OF LISTS!!')
else:
list1.append(elapse)
If you do wish to catch exceptions, ie if it is not a list you can wrap it in a try / except statemnent.
list1 = []
list2 = []
try:
if len(list1) > 50:
list_2.append(elapse)
elif list2 > 50:
print('OUT OF LISTS!!')
else:
list1.append(elapse)
except TypeError:
print('Not a List!!')
Some reading for you:
Error handling:
https://docs.python.org/3/tutorial/errors.html
if /elif`:
https://docs.python.org/3/tutorial/controlflow.html
You an decide which list to append with for instance a ternary operator:
list_to_append = list1 if len(list1) < 50 else list2
list_to_append.append(elapse)
So first we check whether len(list1) < 50. If that is the case, we set list_to_append = list1, otherwise we set list_to_append = list2. We then append to that list.
Please do not name variables things like list, set, dict, etc. Since this will override the reference to the classes with the same name.

Python if else statement in recursive function getting stuck:

so I'm making a function that takes a string and the number of gaps that i need to insert in it, and i want it to output a list of strings of all possible combinations where those gaps are inserted.
I have written a recursive function for that, but the stopping if condition is not being activated no matter what i do. Even printing the expression in itself gives the proper answer but the if condition doesn't follow that expression.
I hope you guys can help with this, even though it's probably a very simple error on my part, i just cant seem to find it.
Thanks in advance.
f = open("bonusoutput.txt",'w')
sequence1 = raw_input("Sequence 1:")
sequence2 = raw_input("Sequence 2:")
l1 = int(len(sequence1))
l2 = int(len(sequence2))
#---------------Function that has problem-----------------------------
def insertBlanks(numGap,string):
if (numGap <= 0):
return [string]
else:
outSeq = []
for cp in range(0,len(string)+1):
outSeq.append(string[:cp] + "_" + string[cp:])
for seq in outSeq:
outSeq += (insertBlanks(numGap-1,seq))
return outSeq
#-------------------------------------------------------------
nGap1 = l2
nGap2 = l1
outSeq2 = insertBlanks(nGap1,sequence2)
f.write(str(outSeq2))
print outSeq2
While looping for seq in outSeq, you are appending items to outSeq. You're returning a list of at least one item each time (base case returns [string] therefore you will add at least 1 item for each item you visit, so you have an infinite loop. Consider adding your output to a new list (or using a list comprehension, like [insertBlanks(numGap - 1, seq) for seq in outSeq]

Categories

Resources