I wrote a python program to print odd permutations of digits 1...9.
list1=[1,2,3,4,5,6,7,8,9] #this is used to generate permutations in lexicographic order
l3=[] #list to store odd permutations
k=7 # initial value of k
l3.append(list1)
while k!=-1:
l=0
#find value of l
for x in range(len(list1)-1,k,-1):
if list1[x]>list1[k]:
l=x
break
#swap values
p=list1[k]
list1[k]=list1[l]
list1[l]=p
#reverse the list
c1=list1[0:k+1]
c2=list1[k+1:]
c2.reverse()
list1=c1+c2
#finiding odd ones and printing them and storing them in l3 list
if list1[8]%2!=0:
l3.append(list1)
print list1 #in next program I replace this line with a for loop to print items in l3 list
k=-1
#find next value of k
for x in range(len(list1)-2,-1,-1):
if list1[x]<list1[x+1]:
k=x
break
This program print the expected results. But when i add this code to end of it instead print line the results changed completely .
for x in l3:
print x
I think I had made some silly mistakes but I can't find any error. plz help me to debug it.(I used permutation generating algorithm in Wikipedia(use k,l variables as mentioned in it).)
This is a copy by reference problem. Just replace the two occurrences of:
l3.append(list1) # cpoy by reference
with:
l3.append(list1[:]) # copy by value
Related
I tried to make a loop that ranges from 1 to 101 and then I tried to add those numbers to a list, but when I run the code, it makes a new line from every number it added so it will look like a huge half pyramid. I want my code to make a single line that shows all numbers in that list.
Here's the code:
nr_random = []
x = 1
for x in range(1, 101):
nr_random.append(x)
print(nr_random)
You can just print the numbers in the list after the for loop executes:
x=1
for x in range(1,101):
nr_random.append(x)
print(nr_random_greu)
I found the answer, just write print(nr_random_greu) outsite the loop
Just create a variable for the last added item:
x=1
nr_random = []
for x in range(1,101):
nr_random.append(x)
last_element = nr_random[-1]
print(last_element)
You are adding numbers to the list (assumed to be nr_random) correctly. Just print the list outside the for loop. Everytime you print it inside it will print the list filled till the ith iteration of the loop on a new line.
I need to keep track of how many times I remove an element from my list. I have something like list remove(an element).
I tried:
c=0
list remove(an element)
c+=1
You must introduce a for loop throughout the list and then use the counter c. and u must initialize c outside the loop and print c outside the loop, like:
c=0
for i in range(0,len(list)):
if element in list:
list.remove(element)
c+=1
print(c)
The difference between the list length before the removal and after will tell you how many you removed.
pre_len = len(list)
list = [x for x in list if x != needle]
num_removed = pre_len - len(list)
Here is my code for comparing two lists and print the output as 1 in lis1 is matched at position 2 in list2 so on..Can you please let me know how i can use nested for loops and break and continue statements
.Also any feasible approach to do this solution
def Iter(l1,l2):
for i in range(len(l1)):
for j in range(len(l2)):
if l1[i]==l2[j]:
print("matched at %d position"%l2[j])
break
l1=[1,2,3,4,5]
l2=[3,4,1,2,5]
Iter(l1,l2)
If I understood your question correctly, you just need to find the position of each item in first list, in the second list.
you can just use one loop to iterate in your first list. for each element you can check if that element exist in the second loop and if so, report the index:
def Iter(l1,l2):
for i,x in enumerate(l1):
try:
print(f"position {i} in first list matched at position {l2.index(x)} in second list")
except ValueError:
continue
the "try" and "except" part is just to handle the error that will arise when you try to use l2.index() on an element that exists in l1 but not l2.
You can simply use one loop if both the arrays are of equal length.
def Iter(l1,l2):
for i in range(len(l1)):
if l1[i]==l2[i]:
print("matched at %d position"%l2[i])
l1=[1,2,3,4,5]
l2=[1,2,1,2,5]
Iter(l1,l2)
output:
matched at 1 position
matched at 2 position
matched at 5 position
Your approach is time-inefficient, it's quadratic time. You can do it in linear time if you allow for linear space. Create a mapping of elements in list2 to their indices:
# assuming unique elements, you can modify to use a lists of indices as values to handle
l1 = [1,2,3,4,5]
l2 = [3,4,1,2,5]
index_map = {val:i for i, val in enumerate(l2)}
for val in l1:
if val in l2:
print(f"Matched {val} at position {index_map[val]}")
I have two lists of ints, a and b, which do not necessarily have the same length. I would like to create new lists from these by removing either the first element of a, or the first element of b, and appending it to the new list, repeating this step until both a and b are empty. At each step in this process, the number of possible lists grows exponentially, and I'd like to know how to generate every list that is possible to create in this way.
So far, I've only managed to work out that the number of possible lists is equal to sum((2**i for i in range(len(a) + len(b)))). I have no idea how to proceed with this, and would appreciate any pointers.
For information, my end goal is to work out the sum of the differences between consecutive elements for each list, and find the minimum of these.
I think this can be achieved by using recursion. Some code.
permutation = [0]*10 # size of this list has to be equal to lenth of list1 + length of list2. (you can have 4 as the size of the list).
def task(list1,list2,index):
if len(list1)==0 and len(list2)==0: # if length of both the list is 0, we print the
print(permutation) # permutation list
return
if len(list1)>0:
permutation[index] = list1[0]
modified_list1 = list1[:] # Since lists in python are passed by reference, I am making a copy of the list
modified_list1.pop(0) # Removing the first element
task(modified_list1,list2,index+1) #and calling the function again using the modified list.
if len(list2)>0:
permutation[index] = list2[0]
modified_list2 = list2[:]
modified_list2.pop(0)
task(list1,modified_list2,index+1)
if __name__=="__main__":
list1 = [1]
list2 = [4,5,6]
task(list1,list2,0)
Recursive solutions can be a little tricky to understand, I will encourage you
to take a copy and pen and try simulating it for small input, you will
understand how things are working.
For your next task, when we are printing the permutation list, you can compute the differences of the adjacent numbers and store your result in any way you want.
I am stuck in making a loop that will eliminate the values(from the alist) that are below average.
Thanks for the help.
a=input("Enter a list of values separated by a coma : ")
alist=eval(a)
print("the list is : ",alist)
average = sum(alist)/len(alist)
print("the average is : ",average)
for i in alist:
if alist[i]<average:
alist.remove[i]
You are almost there. Instead of removing elements, select elements you want to retain instead:
alist = [a for a in alist if a>=average]
Your mistake here is that for i in alist: is iterating over list elements themselves, not indexes, so alist[i] is throwing an error (or returning nonsense).
For the "loop" you can use a filter and a lambda function.
above_average = list(filter(lambda x: x >= average, alist))
For the rest of your code, I suggest you clean it up to something which is safer (use of eval is very bad)
import ast
user_string = raw_input('input a list of numbers separated by a commas: ')
alist = list(ast.literal_eval(user_string)))
So, in all, I would write your code as something like this:
import ast
user_string = raw_input('input a list of numbers separated by a commas: ')
numbers = list(ast.literal_eval(user_string)))
average = sum(numbers)/len(numbers)
print('The numbers: {}'.format(numbers))
print('The average: {}'.format(average))
above_average = list(filter(lambda x: x >= average, numbers))
# now do what you want with the above_average numbers.
Other answers tell you how to do it. I'll tell you why it doesn't work:
You iterate over the list and, at the same time, modify it.
This leads to items being missed during the iteration.
Why?
Internally, the iteration works via an index to the list. So it is the same as doing
idx = 0
while True:
try:
i = alist[idx]
except IndexError:
break
idx += 1
if alist[i] < average:
alist.remove(i)
What happens if you are at the element #3, go to the next one and then remove #3? Right, the indexes of the remaining ones move down and you are pointing to the one which formerly was #5. The old #4 is skipped at this test.
(BTW, I don't know if you noticed, I have replaced your [] behind .remove with ().)
You are mixing two ways of iterating a list: By index, and by element. In your loop, i is not the index, but the element of the list itself, thus alist[i] won't work.
If you use the for x in somelist loop, then x is the element itself, not the index of the element. For iterating over the indices, you can use for i in range(len(somelist)), or you could use for i, x in enumerate(somelist) to loop over tuples of index and element.
Also note that removing elements from a list or other kinds of collections while you are looping them generally is a bad idea. Better create a copy of the list.
for x in list(alist): # creates a copy of alist
if x < average: # remember: x is the element itselt
alist.remove(x) # remove element x from list
But the way you do it (with eval of a comma-separated string of numbers), alist is a tuple, not a list, and thus has no remove method at all. Thus you either have to convert it to a list before (alist = list(eval(a)), or use one of the approaches given in the other answers, creating a new list using list comprehension or filter and retaining the "good" elements.
As a general principle for asking StackOverflow questions like this, you should always include example input and output -- show what happens, and what you expect to happen.
In this case, I believe there are two three problems with your code:
Edit: Third, but possibly most importantly, look at glglgl's answer. If you implement the two fixes I describe below, you'll still have one problem: your code won't necessarily remove all the items you want to remove, because it'll skip over some items.
First, you say alist[i], which grabs the element of alist at index i. But saying for i in alist makes i be successive elements in the list already. Example:
mylist = [1, 2, 4]
for i in mylist:
print(i)
Would give you the output:
1
2
4
If you instead said this (which is like what you wrote)
mylist = [1, 2, 4]
for i in mylist:
print(mylist[i])
It wouldn't work as you'd expect, because you'd get the element at index 1, the element at index 2, and then try to get the element at index 4, but that wouldn't exist. You'll get something like this:
2
4
IndexError: list index out of range
Second, your syntax for removing an element is wrong. You should use alist.remove(i) instead of alist.remove[i]. You want to call a function, so you use parentheses. The square brackets are for indexing and slicing.